diff --git a/src/sim/SConscript b/src/sim/SConscript index fb87bfe69e..700f7025f6 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -84,6 +84,7 @@ Source('power_state.cc') Source('power_domain.cc') Source('stats.cc') Source('workload.cc') +Source('mem_pool.cc') GTest('byteswap.test', 'byteswap.test.cc', '../base/types.cc') GTest('guest_abi.test', 'guest_abi.test.cc') diff --git a/src/sim/mem_pool.cc b/src/sim/mem_pool.cc new file mode 100644 index 0000000000..87132dc634 --- /dev/null +++ b/src/sim/mem_pool.cc @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2011-2021 Advanced Micro Devices, Inc. + * All rights reserved. + * + * For use for simulation and test purposes only + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sim/mem_pool.hh" + +#include "sim/system.hh" + +MemPool::MemPool(System *system, Addr ptr, Addr limit) + : sys(system), freePageNum(ptr >> sys->getPageShift()), + _totalPages(limit >> sys->getPageShift()) +{ +} + +Counter +MemPool::freePage() const +{ + return freePageNum; +} + +void +MemPool::setFreePage(Counter value) +{ + freePageNum = value; +} + +Addr +MemPool::freePageAddr() const +{ + return freePageNum << sys->getPageShift(); +} + +Counter +MemPool::totalPages() const +{ + return _totalPages; +} + +Counter +MemPool::allocatedPages() const +{ + return freePageNum; +} + +Counter +MemPool::freePages() const +{ + return _totalPages - freePageNum; +} + +Addr +MemPool::allocatedBytes() const +{ + return allocatedPages() << sys->getPageShift(); +} + +Addr +MemPool::freeBytes() const +{ + return freePages() << sys->getPageShift(); +} + +Addr +MemPool::totalBytes() const +{ + return totalPages() << sys->getPageShift(); +} + +Addr +MemPool::allocate(Addr npages) +{ + Addr return_addr = freePageAddr(); + freePageNum += npages; + Addr next_return_addr = freePageAddr(); + + if (sys->m5opRange().valid() && + next_return_addr >= sys->m5opRange().start()) { + warn("Reached m5ops MMIO region\n"); + return_addr = sys->m5opRange().end(); + freePageNum = (return_addr >> sys->getPageShift()) + npages; + } + + fatal_if((freePages() <= 0), "Out of memory, " + "please increase size of physical memory."); + + return return_addr; +} diff --git a/src/sim/mem_pool.hh b/src/sim/mem_pool.hh new file mode 100644 index 0000000000..2c99ebc313 --- /dev/null +++ b/src/sim/mem_pool.hh @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011-2021 Advanced Micro Devices, Inc. + * All rights reserved. + * + * For use for simulation and test purposes only + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MEM_POOL_HH__ +#define __MEM_POOL_HH__ + +#include "base/types.hh" + +class System; + +/** Class for handling allocation of physical pages in SE mode. */ +class MemPool +{ + private: + System *sys; + + /** Page number to free memory. */ + Counter freePageNum; + + /** The size of the pool, in number of pages. */ + Counter _totalPages; + + public: + MemPool(System *system, Addr ptr, Addr limit); + + Counter freePage() const; + void setFreePage(Counter value); + Addr freePageAddr() const; + Counter totalPages() const; + + Counter allocatedPages() const; + Counter freePages() const; + + Addr allocatedBytes() const; + Addr freeBytes() const; + Addr totalBytes() const; + + Addr allocate(Addr npages); +}; + +#endif // __MEM_POOL_HH__ diff --git a/src/sim/system.cc b/src/sim/system.cc index 8b23f901ba..b4866ba8ff 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -233,6 +233,19 @@ System::System(const Params &p) } #endif + AddrRangeList memories = physmem.getConfAddrRanges(); + assert(!memories.empty()); + for (const auto &memory : memories) { + assert(!memory.interleaved()); + memPools.emplace_back(this, memory.start(), memory.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) { @@ -362,34 +375,21 @@ System::validKvmEnvironment() const } Addr -System::allocPhysPages(int npages) +System::allocPhysPages(int npages, int poolID) { - Addr return_addr = pagePtr << TheISA::PageShift; - pagePtr += npages; - - Addr next_return_addr = pagePtr << TheISA::PageShift; - - if (_m5opRange.contains(next_return_addr)) { - warn("Reached m5ops MMIO region\n"); - return_addr = 0xffffffff; - pagePtr = 0xffffffff >> TheISA::PageShift; - } - - if ((pagePtr << TheISA::PageShift) > physmem.totalSize()) - fatal("Out of memory, please increase size of physical memory."); - return return_addr; + return memPools[poolID].allocate(npages); } Addr -System::memSize() const +System::memSize(int poolID) const { - return physmem.totalSize(); + return memPools[poolID].totalBytes(); } Addr -System::freeMemSize() const +System::freeMemSize(int poolID) const { - return physmem.totalSize() - (pagePtr << TheISA::PageShift); + return memPools[poolID].freeBytes(); } bool @@ -426,8 +426,6 @@ System::getDeviceMemory(RequestorID id) const void System::serialize(CheckpointOut &cp) const { - SERIALIZE_SCALAR(pagePtr); - for (auto &t: threads.threads) { Tick when = 0; if (t.resumeEvent && t.resumeEvent->scheduled()) @@ -436,6 +434,17 @@ System::serialize(CheckpointOut &cp) const paramOut(cp, csprintf("quiesceEndTick_%d", id), when); } + std::vector ptrs; + std::vector limits; + + for (const auto& memPool : memPools) { + ptrs.push_back(memPool.freePageAddr()); + limits.push_back(memPool.totalBytes()); + } + + SERIALIZE_CONTAINER(ptrs); + SERIALIZE_CONTAINER(limits); + // also serialize the memories in the system physmem.serializeSection(cp, "physmem"); } @@ -444,8 +453,6 @@ System::serialize(CheckpointOut &cp) const void System::unserialize(CheckpointIn &cp) { - UNSERIALIZE_SCALAR(pagePtr); - for (auto &t: threads.threads) { Tick when = 0; ContextID id = t.context->contextId(); @@ -458,6 +465,16 @@ System::unserialize(CheckpointIn &cp) # endif } + std::vector ptrs; + std::vector limits; + + UNSERIALIZE_CONTAINER(ptrs); + UNSERIALIZE_CONTAINER(limits); + + assert(ptrs.size() == limits.size()); + for (size_t i = 0; i < ptrs.size(); i++) + memPools.emplace_back(this, ptrs[i], limits[i]); + // also unserialize the memories in the system physmem.unserializeSection(cp, "physmem"); } diff --git a/src/sim/system.hh b/src/sim/system.hh index acdb316a96..d04c3d2148 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -61,6 +61,7 @@ #include "mem/port_proxy.hh" #include "params/System.hh" #include "sim/futex_map.hh" +#include "sim/mem_pool.hh" #include "sim/redirect_path.hh" #include "sim/se_signal.hh" #include "sim/sim_object.hh" @@ -320,7 +321,8 @@ class System : public SimObject, public PCEventScope bool schedule(PCEvent *event) override; bool remove(PCEvent *event) override; - Addr pagePtr = 0; + /** Memory allocation objects for all physical memories in the system. */ + std::vector memPools; uint64_t init_param; @@ -345,10 +347,10 @@ class System : public SimObject, public PCEventScope PhysicalMemory& getPhysMem() { return physmem; } /** Amount of physical memory that is still free */ - Addr freeMemSize() const; + Addr freeMemSize(int poolID = 0) const; /** Amount of physical memory that exists */ - Addr memSize() const; + Addr memSize(int poolID = 0) const; /** * Check if a physical address is within a range of a memory that @@ -587,7 +589,7 @@ class System : public SimObject, public PCEventScope /// Allocate npages contiguous unused physical pages /// @return Starting address of first page - Addr allocPhysPages(int npages); + Addr allocPhysPages(int npages, int poolID = 0); void registerThreadContext( ThreadContext *tc, ContextID assigned=InvalidContextID);