2017-07-12 14:02:10 +00:00
|
|
|
#include "MemoryMappingHandler.h"
|
|
|
|
#include "MemoryPageEntry.h"
|
|
|
|
|
|
|
|
|
|
|
|
nx::MemoryMappingHandler::MemoryMappingHandler() :
|
|
|
|
mIsSet(false)
|
|
|
|
{}
|
|
|
|
|
|
|
|
bool nx::MemoryMappingHandler::operator==(const MemoryMappingHandler & other) const
|
|
|
|
{
|
|
|
|
return isEqual(other);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool nx::MemoryMappingHandler::operator!=(const MemoryMappingHandler & other) const
|
|
|
|
{
|
|
|
|
return !isEqual(other);
|
|
|
|
}
|
|
|
|
|
|
|
|
void nx::MemoryMappingHandler::operator=(const MemoryMappingHandler & other)
|
|
|
|
{
|
|
|
|
copyFrom(other);
|
|
|
|
}
|
|
|
|
|
|
|
|
void nx::MemoryMappingHandler::importKernelCapabilityList(const fnd::List<KernelCapability>& caps)
|
|
|
|
{
|
2017-07-15 08:28:01 +00:00
|
|
|
if (caps.getSize() == 0)
|
|
|
|
return;
|
2017-07-12 14:02:10 +00:00
|
|
|
|
2017-07-15 08:28:01 +00:00
|
|
|
// get entry list
|
|
|
|
fnd::List<MemoryPageEntry> entries;
|
2017-07-12 14:02:10 +00:00
|
|
|
for (size_t i = 0; i < caps.getSize(); i++)
|
|
|
|
{
|
|
|
|
entries[i].setKernelCapability(caps[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
mMemRange.clear();
|
|
|
|
mMemPage.clear();
|
2017-07-15 08:59:15 +00:00
|
|
|
for (size_t i = 0; i < entries.getSize();)
|
2017-07-12 14:02:10 +00:00
|
|
|
{
|
|
|
|
// has flag means "MemMap"
|
|
|
|
if (entries[i].isMultiplePages())
|
|
|
|
{
|
2017-07-15 08:59:15 +00:00
|
|
|
|
2017-07-12 14:02:10 +00:00
|
|
|
// this entry is the last one or the next one isn't a memory map
|
|
|
|
if ((i + 1) == entries.getSize() || entries[i+1].isMultiplePages() == false)
|
|
|
|
{
|
2017-07-15 08:59:15 +00:00
|
|
|
throw fnd::Exception(kModuleName, "No paired entry");
|
2017-07-12 14:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// check valid page address
|
|
|
|
if (entries[i].getPage() > kMaxPageAddr)
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "Illegal page address");
|
|
|
|
}
|
|
|
|
|
|
|
|
// check valid page num
|
|
|
|
if (entries[i+1].getPage() > kMaxPageAddr)
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "Illegal page num");
|
|
|
|
}
|
|
|
|
|
|
|
|
// add to list
|
2017-07-15 08:59:15 +00:00
|
|
|
mMemRange.addElement({ entries[i].getPage(), entries[i+1].getPage(), entries[i].getFlag() ? MEM_RO : MEM_RW, entries[i+1].getFlag() ? MAP_STATIC : MAP_IO });
|
2017-07-12 14:02:10 +00:00
|
|
|
|
|
|
|
// increment i by two
|
|
|
|
i += 2;
|
|
|
|
}
|
|
|
|
// otherwise means "IoMemMap"
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// check valid page address
|
|
|
|
if (entries[i].getPage() > kMaxPageAddr)
|
|
|
|
{
|
|
|
|
throw fnd::Exception(kModuleName, "Illegal page address");
|
|
|
|
}
|
|
|
|
|
|
|
|
// add to list
|
2017-07-15 08:59:15 +00:00
|
|
|
mMemPage.addElement({ entries[i].getPage(), 1, MEM_RW, MAP_IO });
|
2017-07-12 14:02:10 +00:00
|
|
|
|
|
|
|
// increment i by one
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mIsSet = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nx::MemoryMappingHandler::exportKernelCapabilityList(fnd::List<KernelCapability>& caps) const
|
|
|
|
{
|
|
|
|
if (isSet() == false)
|
|
|
|
return;
|
|
|
|
|
|
|
|
MemoryPageEntry cap;
|
|
|
|
|
|
|
|
// "mem maps"
|
|
|
|
cap.setMapMultiplePages(true);
|
|
|
|
for (size_t i = 0; i < mMemRange.getSize(); i++)
|
|
|
|
{
|
|
|
|
cap.setPage(mMemRange[i].addr & kMaxPageAddr);
|
2017-07-15 08:59:15 +00:00
|
|
|
cap.setFlag(mMemRange[i].perm == MEM_RO);
|
2017-07-12 14:02:10 +00:00
|
|
|
caps.addElement(cap.getKernelCapability());
|
|
|
|
|
|
|
|
cap.setPage(mMemRange[i].size & kMaxPageNum);
|
2017-07-15 08:59:15 +00:00
|
|
|
cap.setFlag(mMemRange[i].type == MAP_STATIC);
|
2017-07-12 14:02:10 +00:00
|
|
|
caps.addElement(cap.getKernelCapability());
|
|
|
|
}
|
|
|
|
|
|
|
|
// "io maps"
|
|
|
|
cap.setMapMultiplePages(false);
|
|
|
|
for (size_t i = 0; i < mMemPage.getSize(); i++)
|
|
|
|
{
|
|
|
|
cap.setPage(mMemPage[i].addr & kMaxPageAddr);
|
|
|
|
caps.addElement(cap.getKernelCapability());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nx::MemoryMappingHandler::clear()
|
|
|
|
{
|
|
|
|
mIsSet = false;
|
|
|
|
mMemRange.clear();
|
|
|
|
mMemPage.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool nx::MemoryMappingHandler::isSet() const
|
|
|
|
{
|
|
|
|
return mIsSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
const fnd::List<nx::MemoryMappingHandler::sMemoryMapping>& nx::MemoryMappingHandler::getMemoryMaps() const
|
|
|
|
{
|
|
|
|
return mMemRange;
|
|
|
|
}
|
|
|
|
|
|
|
|
const fnd::List<nx::MemoryMappingHandler::sMemoryMapping>& nx::MemoryMappingHandler::getIoMemoryMaps() const
|
|
|
|
{
|
|
|
|
return mMemPage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nx::MemoryMappingHandler::copyFrom(const MemoryMappingHandler & other)
|
|
|
|
{
|
|
|
|
mIsSet = other.mIsSet;
|
|
|
|
mMemRange = other.mMemRange;
|
|
|
|
mMemPage = other.mMemPage;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool nx::MemoryMappingHandler::isEqual(const MemoryMappingHandler & other) const
|
|
|
|
{
|
|
|
|
return (mIsSet == other.mIsSet) \
|
|
|
|
&& (mMemRange == other.mMemRange) \
|
|
|
|
&& (mMemPage == other.mMemPage);
|
|
|
|
}
|