|
|
@ -5,6 +5,7 @@ |
|
|
|
|
|
|
|
|
#include <list> |
|
|
#include <list> |
|
|
|
|
|
|
|
|
|
|
|
#include "common/alignment.h" |
|
|
#include "common/assert.h" |
|
|
#include "common/assert.h" |
|
|
#include "common/common_types.h" |
|
|
#include "common/common_types.h" |
|
|
#include "core/hle/kernel/memory_types.h" |
|
|
#include "core/hle/kernel/memory_types.h" |
|
|
@ -12,6 +13,89 @@ |
|
|
|
|
|
|
|
|
namespace Kernel { |
|
|
namespace Kernel { |
|
|
|
|
|
|
|
|
|
|
|
class KPageGroup; |
|
|
|
|
|
|
|
|
|
|
|
class KBlockInfo { |
|
|
|
|
|
private: |
|
|
|
|
|
friend class KPageGroup; |
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
constexpr KBlockInfo() = default; |
|
|
|
|
|
|
|
|
|
|
|
constexpr void Initialize(PAddr addr, size_t np) { |
|
|
|
|
|
ASSERT(Common::IsAligned(addr, PageSize)); |
|
|
|
|
|
ASSERT(static_cast<u32>(np) == np); |
|
|
|
|
|
|
|
|
|
|
|
m_page_index = static_cast<u32>(addr) / PageSize; |
|
|
|
|
|
m_num_pages = static_cast<u32>(np); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constexpr PAddr GetAddress() const { |
|
|
|
|
|
return m_page_index * PageSize; |
|
|
|
|
|
} |
|
|
|
|
|
constexpr size_t GetNumPages() const { |
|
|
|
|
|
return m_num_pages; |
|
|
|
|
|
} |
|
|
|
|
|
constexpr size_t GetSize() const { |
|
|
|
|
|
return this->GetNumPages() * PageSize; |
|
|
|
|
|
} |
|
|
|
|
|
constexpr PAddr GetEndAddress() const { |
|
|
|
|
|
return (m_page_index + m_num_pages) * PageSize; |
|
|
|
|
|
} |
|
|
|
|
|
constexpr PAddr GetLastAddress() const { |
|
|
|
|
|
return this->GetEndAddress() - 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constexpr KBlockInfo* GetNext() const { |
|
|
|
|
|
return m_next; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constexpr bool IsEquivalentTo(const KBlockInfo& rhs) const { |
|
|
|
|
|
return m_page_index == rhs.m_page_index && m_num_pages == rhs.m_num_pages; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constexpr bool operator==(const KBlockInfo& rhs) const { |
|
|
|
|
|
return this->IsEquivalentTo(rhs); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constexpr bool operator!=(const KBlockInfo& rhs) const { |
|
|
|
|
|
return !(*this == rhs); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constexpr bool IsStrictlyBefore(PAddr addr) const { |
|
|
|
|
|
const PAddr end = this->GetEndAddress(); |
|
|
|
|
|
|
|
|
|
|
|
if (m_page_index != 0 && end == 0) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return end < addr; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constexpr bool operator<(PAddr addr) const { |
|
|
|
|
|
return this->IsStrictlyBefore(addr); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constexpr bool TryConcatenate(PAddr addr, size_t np) { |
|
|
|
|
|
if (addr != 0 && addr == this->GetEndAddress()) { |
|
|
|
|
|
m_num_pages += static_cast<u32>(np); |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
constexpr void SetNext(KBlockInfo* next) { |
|
|
|
|
|
m_next = next; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
KBlockInfo* m_next{}; |
|
|
|
|
|
u32 m_page_index{}; |
|
|
|
|
|
u32 m_num_pages{}; |
|
|
|
|
|
}; |
|
|
|
|
|
static_assert(sizeof(KBlockInfo) <= 0x10); |
|
|
|
|
|
|
|
|
class KPageGroup final { |
|
|
class KPageGroup final { |
|
|
public: |
|
|
public: |
|
|
class Node final { |
|
|
class Node final { |
|
|
@ -92,6 +176,8 @@ public: |
|
|
return nodes.empty(); |
|
|
return nodes.empty(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Finalize() {} |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
std::list<Node> nodes; |
|
|
std::list<Node> nodes; |
|
|
}; |
|
|
}; |
|
|
|