|
|
@@ -5,6 +5,7 @@
|
|
|
|
|
|
#include <list>
|
|
|
|
|
|
+#include "common/alignment.h"
|
|
|
#include "common/assert.h"
|
|
|
#include "common/common_types.h"
|
|
|
#include "core/hle/kernel/memory_types.h"
|
|
|
@@ -12,6 +13,89 @@
|
|
|
|
|
|
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 {
|
|
|
public:
|
|
|
class Node final {
|
|
|
@@ -92,6 +176,8 @@ public:
|
|
|
return nodes.empty();
|
|
|
}
|
|
|
|
|
|
+ void Finalize() {}
|
|
|
+
|
|
|
private:
|
|
|
std::list<Node> nodes;
|
|
|
};
|