121 lines
2.8 KiB
C++
121 lines
2.8 KiB
C++
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "core/hle/kernel/k_dynamic_resource_manager.h"
|
|
#include "core/hle/kernel/k_memory_manager.h"
|
|
#include "core/hle/kernel/k_page_group.h"
|
|
#include "core/hle/kernel/kernel.h"
|
|
#include "core/hle/kernel/svc_results.h"
|
|
|
|
namespace Kernel {
|
|
|
|
void KPageGroup::Finalize() {
|
|
KBlockInfo* cur = m_first_block;
|
|
while (cur != nullptr) {
|
|
KBlockInfo* next = cur->GetNext();
|
|
m_manager->Free(cur);
|
|
cur = next;
|
|
}
|
|
|
|
m_first_block = nullptr;
|
|
m_last_block = nullptr;
|
|
}
|
|
|
|
void KPageGroup::CloseAndReset() {
|
|
auto& mm = m_kernel.MemoryManager();
|
|
|
|
KBlockInfo* cur = m_first_block;
|
|
while (cur != nullptr) {
|
|
KBlockInfo* next = cur->GetNext();
|
|
mm.Close(cur->GetAddress(), cur->GetNumPages());
|
|
m_manager->Free(cur);
|
|
cur = next;
|
|
}
|
|
|
|
m_first_block = nullptr;
|
|
m_last_block = nullptr;
|
|
}
|
|
|
|
size_t KPageGroup::GetNumPages() const {
|
|
size_t num_pages = 0;
|
|
|
|
for (const auto& it : *this) {
|
|
num_pages += it.GetNumPages();
|
|
}
|
|
|
|
return num_pages;
|
|
}
|
|
|
|
Result KPageGroup::AddBlock(KPhysicalAddress addr, size_t num_pages) {
|
|
// Succeed immediately if we're adding no pages.
|
|
R_SUCCEED_IF(num_pages == 0);
|
|
|
|
// Check for overflow.
|
|
ASSERT(addr < addr + num_pages * PageSize);
|
|
|
|
// Try to just append to the last block.
|
|
if (m_last_block != nullptr) {
|
|
R_SUCCEED_IF(m_last_block->TryConcatenate(addr, num_pages));
|
|
}
|
|
|
|
// Allocate a new block.
|
|
KBlockInfo* new_block = m_manager->Allocate();
|
|
R_UNLESS(new_block != nullptr, ResultOutOfResource);
|
|
|
|
// Initialize the block.
|
|
new_block->Initialize(addr, num_pages);
|
|
|
|
// Add the block to our list.
|
|
if (m_last_block != nullptr) {
|
|
m_last_block->SetNext(new_block);
|
|
} else {
|
|
m_first_block = new_block;
|
|
}
|
|
m_last_block = new_block;
|
|
|
|
R_SUCCEED();
|
|
}
|
|
|
|
void KPageGroup::Open() const {
|
|
auto& mm = m_kernel.MemoryManager();
|
|
|
|
for (const auto& it : *this) {
|
|
mm.Open(it.GetAddress(), it.GetNumPages());
|
|
}
|
|
}
|
|
|
|
void KPageGroup::OpenFirst() const {
|
|
auto& mm = m_kernel.MemoryManager();
|
|
|
|
for (const auto& it : *this) {
|
|
mm.OpenFirst(it.GetAddress(), it.GetNumPages());
|
|
}
|
|
}
|
|
|
|
void KPageGroup::Close() const {
|
|
auto& mm = m_kernel.MemoryManager();
|
|
|
|
for (const auto& it : *this) {
|
|
mm.Close(it.GetAddress(), it.GetNumPages());
|
|
}
|
|
}
|
|
|
|
bool KPageGroup::IsEquivalentTo(const KPageGroup& rhs) const {
|
|
auto lit = this->begin();
|
|
auto rit = rhs.begin();
|
|
auto lend = this->end();
|
|
auto rend = rhs.end();
|
|
|
|
while (lit != lend && rit != rend) {
|
|
if (*lit != *rit) {
|
|
return false;
|
|
}
|
|
|
|
++lit;
|
|
++rit;
|
|
}
|
|
|
|
return lit == lend && rit == rend;
|
|
}
|
|
|
|
} // namespace Kernel
|