Implemented MapPhysicalMemory & UnmapPhysicalMemory

This commit is contained in:
David Marcec
2018-12-01 16:03:18 +11:00
parent b7104263ba
commit ba079516cf
8 changed files with 379 additions and 70 deletions

View File

@@ -18,6 +18,20 @@ enum class ProgramAddressSpaceType : u8;
namespace Kernel {
// Checks if address + size is greater than the given address
// This can return false if the size causes an overflow of a 64-bit type
// or if the given size is zero.
constexpr bool IsValidAddressRange(VAddr address, u64 size) {
return address + size > address;
}
// Checks if a given address range lies within a larger address range.
constexpr bool IsInsideAddressRange(VAddr address, u64 size, VAddr address_range_begin,
VAddr address_range_end) {
const VAddr end_address = address + size - 1;
return address_range_begin <= address && end_address <= address_range_end - 1;
}
enum class VMAType : u8 {
/// VMA represents an unmapped region of the address space.
Free,
@@ -165,6 +179,30 @@ public:
*/
ResultVal<VAddr> FindFreeRegion(u64 size) const;
/**
* Maps memory to the PersonalMmHeap region at a given address. MapPhysicalMemory will not remap
* any regions. The goal of MapPhysicalMemory is to "fill" a regions empty space given an offset
* and a size. Any memory which is already mapped in the subsection we want to allocate is
* ignored and we only map the remaining data needed. Reminder that we're not remapping, just
* filling the space we want to fill. This is typically used with "PersonalMmHeap" which allows
* processes to have extra resources mapped. Typically this is seen with 5.0.0+ games and
* sysmodule specifically. The PersonalMmHeapSize is pulled from the NPDM and is passed to
* loader when the process is created which is in turn passed to the kernel when
* svcCreateProcess is called
*
* @param target The address of where you want to map
* @param size The size of the memory you want to map
*/
ResultCode MapPhysicalMemory(VAddr target, u64 size);
/**
* Unmaps memory from the PersonalMmHeap region at a given address.
*
* @param target The address of where you want to unmap
* @param size The size of the memory you want to unmap
*/
ResultCode UnmapPhysicalMemory(VAddr target, u64 size);
/**
* Maps a memory-mapped IO region at a given address.
*
@@ -276,6 +314,13 @@ public:
/// Gets the total size of the TLS IO region in bytes.
u64 GetTLSIORegionSize() const;
/// Gets the total size of the PersonalMmHeap region in bytes.
u64 GetPersonalMmHeapUsage() const;
bool IsInsideAddressSpace(VAddr address, u64 size) const;
bool IsInsideNewMapRegion(VAddr address, u64 size) const;
bool IsInsideMapRegion(VAddr address, u64 size) const;
/// Each VMManager has its own page table, which is set as the main one when the owning process
/// is scheduled.
Memory::PageTable page_table;
@@ -359,5 +404,7 @@ private:
VAddr heap_start = 0;
VAddr heap_end = 0;
u64 heap_used = 0;
u64 personal_heap_usage = 0;
};
} // namespace Kernel