11 changed files with 270 additions and 125 deletions
-
1src/core/CMakeLists.txt
-
29src/core/hle/kernel/k_code_memory.cpp
-
6src/core/hle/kernel/k_code_memory.h
-
8src/core/hle/kernel/k_memory_manager.cpp
-
121src/core/hle/kernel/k_page_group.cpp
-
154src/core/hle/kernel/k_page_group.h
-
39src/core/hle/kernel/k_page_table.cpp
-
5src/core/hle/kernel/k_page_table.h
-
19src/core/hle/kernel/k_shared_memory.cpp
-
3src/core/hle/kernel/memory_types.h
-
2src/core/hle/kernel/svc.cpp
@ -0,0 +1,121 @@ |
|||
// 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
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue