Browse Source
Merge pull request #9173 from bunnei/kern-update-15
Merge pull request #9173 from bunnei/kern-update-15
Kernel: Various updates for FW 15.0.xpull/15/merge
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 2786 additions and 737 deletions
-
6src/core/CMakeLists.txt
-
4src/core/hle/kernel/board/nintendo/nx/k_system_control.h
-
74src/core/hle/kernel/init/init_slab_setup.cpp
-
2src/core/hle/kernel/init/init_slab_setup.h
-
3src/core/hle/kernel/k_class_token.cpp
-
6src/core/hle/kernel/k_class_token.h
-
20src/core/hle/kernel/k_debug.h
-
67src/core/hle/kernel/k_dynamic_page_manager.h
-
3src/core/hle/kernel/k_dynamic_resource_manager.h
-
64src/core/hle/kernel/k_event_info.h
-
33src/core/hle/kernel/k_handle_table.cpp
-
106src/core/hle/kernel/k_handle_table.h
-
110src/core/hle/kernel/k_memory_block.h
-
10src/core/hle/kernel/k_memory_layout.cpp
-
19src/core/hle/kernel/k_memory_layout.h
-
270src/core/hle/kernel/k_memory_manager.cpp
-
259src/core/hle/kernel/k_memory_manager.h
-
123src/core/hle/kernel/k_memory_region_type.h
-
243src/core/hle/kernel/k_page_bitmap.h
-
14src/core/hle/kernel/k_page_buffer.h
-
86src/core/hle/kernel/k_page_group.h
-
86src/core/hle/kernel/k_page_heap.cpp
-
39src/core/hle/kernel/k_page_heap.h
-
1129src/core/hle/kernel/k_page_table.cpp
-
142src/core/hle/kernel/k_page_table.h
-
55src/core/hle/kernel/k_page_table_manager.h
-
93src/core/hle/kernel/k_page_table_slab_heap.h
-
4src/core/hle/kernel/k_process.cpp
-
26src/core/hle/kernel/k_system_resource.cpp
-
137src/core/hle/kernel/k_system_resource.h
-
127src/core/hle/kernel/kernel.cpp
-
23src/core/hle/kernel/kernel.h
-
78src/core/hle/kernel/slab_helpers.h
-
2src/core/hle/kernel/svc.cpp
-
1src/core/hle/kernel/svc_results.h
-
40src/core/hle/kernel/svc_types.h
-
13src/core/hle/result.h
-
6src/core/hle/service/nvdrv/devices/nvmap.cpp
@ -0,0 +1,20 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "core/hle/kernel/k_auto_object.h" |
|||
#include "core/hle/kernel/slab_helpers.h" |
|||
|
|||
namespace Kernel { |
|||
|
|||
class KDebug final : public KAutoObjectWithSlabHeapAndContainer<KDebug, KAutoObjectWithList> { |
|||
KERNEL_AUTOOBJECT_TRAITS(KDebug, KAutoObject); |
|||
|
|||
public: |
|||
explicit KDebug(KernelCore& kernel_) : KAutoObjectWithSlabHeapAndContainer{kernel_} {} |
|||
|
|||
static void PostDestroy([[maybe_unused]] uintptr_t arg) {} |
|||
}; |
|||
|
|||
} // namespace Kernel |
|||
@ -0,0 +1,64 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
|
|||
#include <boost/intrusive/list.hpp> |
|||
|
|||
#include "core/hle/kernel/slab_helpers.h" |
|||
#include "core/hle/kernel/svc_types.h" |
|||
|
|||
namespace Kernel { |
|||
|
|||
class KEventInfo : public KSlabAllocated<KEventInfo>, public boost::intrusive::list_base_hook<> { |
|||
public: |
|||
struct InfoCreateThread { |
|||
u32 thread_id{}; |
|||
uintptr_t tls_address{}; |
|||
}; |
|||
|
|||
struct InfoExitProcess { |
|||
Svc::ProcessExitReason reason{}; |
|||
}; |
|||
|
|||
struct InfoExitThread { |
|||
Svc::ThreadExitReason reason{}; |
|||
}; |
|||
|
|||
struct InfoException { |
|||
Svc::DebugException exception_type{}; |
|||
s32 exception_data_count{}; |
|||
uintptr_t exception_address{}; |
|||
std::array<uintptr_t, 4> exception_data{}; |
|||
}; |
|||
|
|||
struct InfoSystemCall { |
|||
s64 tick{}; |
|||
s32 id{}; |
|||
}; |
|||
|
|||
public: |
|||
KEventInfo() = default; |
|||
~KEventInfo() = default; |
|||
|
|||
public: |
|||
Svc::DebugEvent event{}; |
|||
u32 thread_id{}; |
|||
u32 flags{}; |
|||
bool is_attached{}; |
|||
bool continue_flag{}; |
|||
bool ignore_continue{}; |
|||
bool close_once{}; |
|||
union { |
|||
InfoCreateThread create_thread; |
|||
InfoExitProcess exit_process; |
|||
InfoExitThread exit_thread; |
|||
InfoException exception; |
|||
InfoSystemCall system_call; |
|||
} info{}; |
|||
KThread* debug_thread{}; |
|||
}; |
|||
|
|||
} // namespace Kernel |
|||
1129
src/core/hle/kernel/k_page_table.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,55 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <atomic> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/kernel/k_dynamic_resource_manager.h" |
|||
#include "core/hle/kernel/k_page_table_slab_heap.h" |
|||
|
|||
namespace Kernel { |
|||
|
|||
class KPageTableManager : public KDynamicResourceManager<impl::PageTablePage, true> { |
|||
public: |
|||
using RefCount = KPageTableSlabHeap::RefCount; |
|||
static constexpr size_t PageTableSize = KPageTableSlabHeap::PageTableSize; |
|||
|
|||
public: |
|||
KPageTableManager() = default; |
|||
|
|||
void Initialize(KDynamicPageManager* page_allocator, KPageTableSlabHeap* pt_heap) { |
|||
m_pt_heap = pt_heap; |
|||
|
|||
static_assert(std::derived_from<KPageTableSlabHeap, DynamicSlabType>); |
|||
BaseHeap::Initialize(page_allocator, pt_heap); |
|||
} |
|||
|
|||
VAddr Allocate() { |
|||
return VAddr(BaseHeap::Allocate()); |
|||
} |
|||
|
|||
RefCount GetRefCount(VAddr addr) const { |
|||
return m_pt_heap->GetRefCount(addr); |
|||
} |
|||
|
|||
void Open(VAddr addr, int count) { |
|||
return m_pt_heap->Open(addr, count); |
|||
} |
|||
|
|||
bool Close(VAddr addr, int count) { |
|||
return m_pt_heap->Close(addr, count); |
|||
} |
|||
|
|||
bool IsInPageTableHeap(VAddr addr) const { |
|||
return m_pt_heap->IsInRange(addr); |
|||
} |
|||
|
|||
private: |
|||
using BaseHeap = KDynamicResourceManager<impl::PageTablePage, true>; |
|||
|
|||
KPageTableSlabHeap* m_pt_heap{}; |
|||
}; |
|||
|
|||
} // namespace Kernel |
|||
@ -0,0 +1,93 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <vector> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "core/hle/kernel/k_dynamic_slab_heap.h" |
|||
#include "core/hle/kernel/slab_helpers.h" |
|||
|
|||
namespace Kernel { |
|||
|
|||
namespace impl { |
|||
|
|||
class PageTablePage { |
|||
public: |
|||
// Do not initialize anything. |
|||
PageTablePage() = default; |
|||
|
|||
private: |
|||
std::array<u8, PageSize> m_buffer{}; |
|||
}; |
|||
static_assert(sizeof(PageTablePage) == PageSize); |
|||
|
|||
} // namespace impl |
|||
|
|||
class KPageTableSlabHeap : public KDynamicSlabHeap<impl::PageTablePage, true> { |
|||
public: |
|||
using RefCount = u16; |
|||
static constexpr size_t PageTableSize = sizeof(impl::PageTablePage); |
|||
static_assert(PageTableSize == PageSize); |
|||
|
|||
public: |
|||
KPageTableSlabHeap() = default; |
|||
|
|||
static constexpr size_t CalculateReferenceCountSize(size_t size) { |
|||
return (size / PageSize) * sizeof(RefCount); |
|||
} |
|||
|
|||
void Initialize(KDynamicPageManager* page_allocator, size_t object_count, RefCount* rc) { |
|||
BaseHeap::Initialize(page_allocator, object_count); |
|||
this->Initialize(rc); |
|||
} |
|||
|
|||
RefCount GetRefCount(VAddr addr) { |
|||
ASSERT(this->IsInRange(addr)); |
|||
return *this->GetRefCountPointer(addr); |
|||
} |
|||
|
|||
void Open(VAddr addr, int count) { |
|||
ASSERT(this->IsInRange(addr)); |
|||
|
|||
*this->GetRefCountPointer(addr) += static_cast<RefCount>(count); |
|||
|
|||
ASSERT(this->GetRefCount(addr) > 0); |
|||
} |
|||
|
|||
bool Close(VAddr addr, int count) { |
|||
ASSERT(this->IsInRange(addr)); |
|||
ASSERT(this->GetRefCount(addr) >= count); |
|||
|
|||
*this->GetRefCountPointer(addr) -= static_cast<RefCount>(count); |
|||
return this->GetRefCount(addr) == 0; |
|||
} |
|||
|
|||
bool IsInPageTableHeap(VAddr addr) const { |
|||
return this->IsInRange(addr); |
|||
} |
|||
|
|||
private: |
|||
void Initialize([[maybe_unused]] RefCount* rc) { |
|||
// TODO(bunnei): Use rc once we support kernel virtual memory allocations. |
|||
const auto count = this->GetSize() / PageSize; |
|||
m_ref_counts.resize(count); |
|||
|
|||
for (size_t i = 0; i < count; i++) { |
|||
m_ref_counts[i] = 0; |
|||
} |
|||
} |
|||
|
|||
RefCount* GetRefCountPointer(VAddr addr) { |
|||
return m_ref_counts.data() + ((addr - this->GetAddress()) / PageSize); |
|||
} |
|||
|
|||
private: |
|||
using BaseHeap = KDynamicSlabHeap<impl::PageTablePage, true>; |
|||
|
|||
std::vector<RefCount> m_ref_counts; |
|||
}; |
|||
|
|||
} // namespace Kernel |
|||
@ -0,0 +1,26 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "core/hle/kernel/k_system_resource.h"
|
|||
|
|||
namespace Kernel { |
|||
|
|||
Result KSecureSystemResource::Initialize([[maybe_unused]] size_t size, |
|||
[[maybe_unused]] KResourceLimit* resource_limit, |
|||
[[maybe_unused]] KMemoryManager::Pool pool) { |
|||
// Unimplemented
|
|||
UNREACHABLE(); |
|||
} |
|||
|
|||
void KSecureSystemResource::Finalize() { |
|||
// Unimplemented
|
|||
UNREACHABLE(); |
|||
} |
|||
|
|||
size_t KSecureSystemResource::CalculateRequiredSecureMemorySize( |
|||
[[maybe_unused]] size_t size, [[maybe_unused]] KMemoryManager::Pool pool) { |
|||
// Unimplemented
|
|||
UNREACHABLE(); |
|||
} |
|||
|
|||
} // namespace Kernel
|
|||
@ -0,0 +1,137 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "common/assert.h" |
|||
#include "common/common_types.h" |
|||
#include "core/hle/kernel/k_auto_object.h" |
|||
#include "core/hle/kernel/k_dynamic_resource_manager.h" |
|||
#include "core/hle/kernel/k_memory_manager.h" |
|||
#include "core/hle/kernel/k_page_table_manager.h" |
|||
#include "core/hle/kernel/k_resource_limit.h" |
|||
#include "core/hle/kernel/slab_helpers.h" |
|||
|
|||
namespace Kernel { |
|||
|
|||
// NOTE: Nintendo's implementation does not have the "is_secure_resource" field, and instead uses |
|||
// virtual IsSecureResource(). |
|||
|
|||
class KSystemResource : public KAutoObject { |
|||
KERNEL_AUTOOBJECT_TRAITS(KSystemResource, KAutoObject); |
|||
|
|||
public: |
|||
explicit KSystemResource(KernelCore& kernel_) : KAutoObject(kernel_) {} |
|||
|
|||
protected: |
|||
void SetSecureResource() { |
|||
m_is_secure_resource = true; |
|||
} |
|||
|
|||
public: |
|||
virtual void Destroy() override { |
|||
UNREACHABLE_MSG("KSystemResource::Destroy() was called"); |
|||
} |
|||
|
|||
bool IsSecureResource() const { |
|||
return m_is_secure_resource; |
|||
} |
|||
|
|||
void SetManagers(KMemoryBlockSlabManager& mb, KBlockInfoManager& bi, KPageTableManager& pt) { |
|||
ASSERT(m_p_memory_block_slab_manager == nullptr); |
|||
ASSERT(m_p_block_info_manager == nullptr); |
|||
ASSERT(m_p_page_table_manager == nullptr); |
|||
|
|||
m_p_memory_block_slab_manager = std::addressof(mb); |
|||
m_p_block_info_manager = std::addressof(bi); |
|||
m_p_page_table_manager = std::addressof(pt); |
|||
} |
|||
|
|||
const KMemoryBlockSlabManager& GetMemoryBlockSlabManager() const { |
|||
return *m_p_memory_block_slab_manager; |
|||
} |
|||
const KBlockInfoManager& GetBlockInfoManager() const { |
|||
return *m_p_block_info_manager; |
|||
} |
|||
const KPageTableManager& GetPageTableManager() const { |
|||
return *m_p_page_table_manager; |
|||
} |
|||
|
|||
KMemoryBlockSlabManager& GetMemoryBlockSlabManager() { |
|||
return *m_p_memory_block_slab_manager; |
|||
} |
|||
KBlockInfoManager& GetBlockInfoManager() { |
|||
return *m_p_block_info_manager; |
|||
} |
|||
KPageTableManager& GetPageTableManager() { |
|||
return *m_p_page_table_manager; |
|||
} |
|||
|
|||
KMemoryBlockSlabManager* GetMemoryBlockSlabManagerPointer() { |
|||
return m_p_memory_block_slab_manager; |
|||
} |
|||
KBlockInfoManager* GetBlockInfoManagerPointer() { |
|||
return m_p_block_info_manager; |
|||
} |
|||
KPageTableManager* GetPageTableManagerPointer() { |
|||
return m_p_page_table_manager; |
|||
} |
|||
|
|||
private: |
|||
KMemoryBlockSlabManager* m_p_memory_block_slab_manager{}; |
|||
KBlockInfoManager* m_p_block_info_manager{}; |
|||
KPageTableManager* m_p_page_table_manager{}; |
|||
bool m_is_secure_resource{false}; |
|||
}; |
|||
|
|||
class KSecureSystemResource final |
|||
: public KAutoObjectWithSlabHeap<KSecureSystemResource, KSystemResource> { |
|||
public: |
|||
explicit KSecureSystemResource(KernelCore& kernel_) |
|||
: KAutoObjectWithSlabHeap<KSecureSystemResource, KSystemResource>(kernel_) { |
|||
// Mark ourselves as being a secure resource. |
|||
this->SetSecureResource(); |
|||
} |
|||
|
|||
Result Initialize(size_t size, KResourceLimit* resource_limit, KMemoryManager::Pool pool); |
|||
void Finalize(); |
|||
|
|||
bool IsInitialized() const { |
|||
return m_is_initialized; |
|||
} |
|||
static void PostDestroy([[maybe_unused]] uintptr_t arg) {} |
|||
|
|||
size_t CalculateRequiredSecureMemorySize() const { |
|||
return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool); |
|||
} |
|||
|
|||
size_t GetSize() const { |
|||
return m_resource_size; |
|||
} |
|||
size_t GetUsedSize() const { |
|||
return m_dynamic_page_manager.GetUsed() * PageSize; |
|||
} |
|||
|
|||
const KDynamicPageManager& GetDynamicPageManager() const { |
|||
return m_dynamic_page_manager; |
|||
} |
|||
|
|||
public: |
|||
static size_t CalculateRequiredSecureMemorySize(size_t size, KMemoryManager::Pool pool); |
|||
|
|||
private: |
|||
bool m_is_initialized{}; |
|||
KMemoryManager::Pool m_resource_pool{}; |
|||
KDynamicPageManager m_dynamic_page_manager; |
|||
KMemoryBlockSlabManager m_memory_block_slab_manager; |
|||
KBlockInfoManager m_block_info_manager; |
|||
KPageTableManager m_page_table_manager; |
|||
KMemoryBlockSlabHeap m_memory_block_heap; |
|||
KBlockInfoSlabHeap m_block_info_heap; |
|||
KPageTableSlabHeap m_page_table_heap; |
|||
KResourceLimit* m_resource_limit{}; |
|||
VAddr m_resource_address{}; |
|||
size_t m_resource_size{}; |
|||
}; |
|||
|
|||
} // namespace Kernel |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue