| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- // 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
|