mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-09-07 04:09:08 +01:00
core: hle: kernel: Integrate system KSystemResource.
This commit is contained in:
parent
b7b47f3099
commit
32d7faafa8
7 changed files with 209 additions and 69 deletions
|
@ -10,7 +10,9 @@
|
||||||
#include "core/hardware_properties.h"
|
#include "core/hardware_properties.h"
|
||||||
#include "core/hle/kernel/init/init_slab_setup.h"
|
#include "core/hle/kernel/init/init_slab_setup.h"
|
||||||
#include "core/hle/kernel/k_code_memory.h"
|
#include "core/hle/kernel/k_code_memory.h"
|
||||||
|
#include "core/hle/kernel/k_debug.h"
|
||||||
#include "core/hle/kernel/k_event.h"
|
#include "core/hle/kernel/k_event.h"
|
||||||
|
#include "core/hle/kernel/k_event_info.h"
|
||||||
#include "core/hle/kernel/k_memory_layout.h"
|
#include "core/hle/kernel/k_memory_layout.h"
|
||||||
#include "core/hle/kernel/k_memory_manager.h"
|
#include "core/hle/kernel/k_memory_manager.h"
|
||||||
#include "core/hle/kernel/k_page_buffer.h"
|
#include "core/hle/kernel/k_page_buffer.h"
|
||||||
|
@ -22,6 +24,7 @@
|
||||||
#include "core/hle/kernel/k_shared_memory.h"
|
#include "core/hle/kernel/k_shared_memory.h"
|
||||||
#include "core/hle/kernel/k_shared_memory_info.h"
|
#include "core/hle/kernel/k_shared_memory_info.h"
|
||||||
#include "core/hle/kernel/k_system_control.h"
|
#include "core/hle/kernel/k_system_control.h"
|
||||||
|
#include "core/hle/kernel/k_system_resource.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
#include "core/hle/kernel/k_thread_local_page.h"
|
#include "core/hle/kernel/k_thread_local_page.h"
|
||||||
#include "core/hle/kernel/k_transfer_memory.h"
|
#include "core/hle/kernel/k_transfer_memory.h"
|
||||||
|
@ -44,7 +47,10 @@ namespace Kernel::Init {
|
||||||
HANDLER(KThreadLocalPage, \
|
HANDLER(KThreadLocalPage, \
|
||||||
(SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \
|
(SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \
|
||||||
##__VA_ARGS__) \
|
##__VA_ARGS__) \
|
||||||
HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__)
|
HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \
|
||||||
|
HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
|
||||||
|
HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
|
||||||
|
HANDLER(KSecureSystemResource, (SLAB_COUNT(KProcess)), ##__VA_ARGS__)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -73,8 +79,20 @@ constexpr size_t SlabCountKResourceLimit = 5;
|
||||||
constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES;
|
constexpr size_t SlabCountKDebug = Core::Hardware::NUM_CPU_CORES;
|
||||||
constexpr size_t SlabCountKIoPool = 1;
|
constexpr size_t SlabCountKIoPool = 1;
|
||||||
constexpr size_t SlabCountKIoRegion = 6;
|
constexpr size_t SlabCountKIoRegion = 6;
|
||||||
|
constexpr size_t SlabcountKSessionRequestMappings = 40;
|
||||||
|
|
||||||
constexpr size_t SlabCountExtraKThread = 160;
|
constexpr size_t SlabCountExtraKThread = (1024 + 256 + 256) - SlabCountKThread;
|
||||||
|
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
static_assert(KernelPageBufferHeapSize ==
|
||||||
|
2 * PageSize + (SlabCountKProcess + SlabCountKThread +
|
||||||
|
(SlabCountKProcess + SlabCountKThread) / 8) *
|
||||||
|
PageSize);
|
||||||
|
static_assert(KernelPageBufferAdditionalSize ==
|
||||||
|
(SlabCountExtraKThread + (SlabCountExtraKThread / 8)) * PageSize);
|
||||||
|
|
||||||
|
} // namespace test
|
||||||
|
|
||||||
/// Helper function to translate from the slab virtual address to the reserved location in physical
|
/// Helper function to translate from the slab virtual address to the reserved location in physical
|
||||||
/// memory.
|
/// memory.
|
||||||
|
@ -109,7 +127,7 @@ VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAd
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CalculateSlabHeapGapSize() {
|
size_t CalculateSlabHeapGapSize() {
|
||||||
constexpr size_t KernelSlabHeapGapSize = 2_MiB - 296_KiB;
|
constexpr size_t KernelSlabHeapGapSize = 2_MiB - 320_KiB;
|
||||||
static_assert(KernelSlabHeapGapSize <= KernelSlabHeapGapsSizeMax);
|
static_assert(KernelSlabHeapGapSize <= KernelSlabHeapGapsSizeMax);
|
||||||
return KernelSlabHeapGapSize;
|
return KernelSlabHeapGapSize;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +152,7 @@ KSlabResourceCounts KSlabResourceCounts::CreateDefault() {
|
||||||
.num_KDebug = SlabCountKDebug,
|
.num_KDebug = SlabCountKDebug,
|
||||||
.num_KIoPool = SlabCountKIoPool,
|
.num_KIoPool = SlabCountKIoPool,
|
||||||
.num_KIoRegion = SlabCountKIoRegion,
|
.num_KIoRegion = SlabCountKIoRegion,
|
||||||
|
.num_KSessionRequestMappings = SlabcountKSessionRequestMappings,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,29 +183,6 @@ size_t CalculateTotalSlabHeapSize(const KernelCore& kernel) {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeKPageBufferSlabHeap(Core::System& system) {
|
|
||||||
auto& kernel = system.Kernel();
|
|
||||||
|
|
||||||
const auto& counts = kernel.SlabResourceCounts();
|
|
||||||
const size_t num_pages =
|
|
||||||
counts.num_KProcess + counts.num_KThread + (counts.num_KProcess + counts.num_KThread) / 8;
|
|
||||||
const size_t slab_size = num_pages * PageSize;
|
|
||||||
|
|
||||||
// Reserve memory from the system resource limit.
|
|
||||||
ASSERT(kernel.GetSystemResourceLimit()->Reserve(LimitableResource::PhysicalMemory, slab_size));
|
|
||||||
|
|
||||||
// Allocate memory for the slab.
|
|
||||||
constexpr auto AllocateOption = KMemoryManager::EncodeOption(
|
|
||||||
KMemoryManager::Pool::System, KMemoryManager::Direction::FromFront);
|
|
||||||
const PAddr slab_address =
|
|
||||||
kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, AllocateOption);
|
|
||||||
ASSERT(slab_address != 0);
|
|
||||||
|
|
||||||
// Initialize the slabheap.
|
|
||||||
KPageBuffer::InitializeSlabHeap(kernel, system.DeviceMemory().GetPointer<void>(slab_address),
|
|
||||||
slab_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
|
void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
|
||||||
auto& kernel = system.Kernel();
|
auto& kernel = system.Kernel();
|
||||||
|
|
||||||
|
@ -258,3 +254,29 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Kernel::Init
|
} // namespace Kernel::Init
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
void KPageBufferSlabHeap::Initialize(Core::System& system) {
|
||||||
|
auto& kernel = system.Kernel();
|
||||||
|
const auto& counts = kernel.SlabResourceCounts();
|
||||||
|
const size_t num_pages =
|
||||||
|
counts.num_KProcess + counts.num_KThread + (counts.num_KProcess + counts.num_KThread) / 8;
|
||||||
|
const size_t slab_size = num_pages * PageSize;
|
||||||
|
|
||||||
|
// Reserve memory from the system resource limit.
|
||||||
|
ASSERT(kernel.GetSystemResourceLimit()->Reserve(LimitableResource::PhysicalMemory, slab_size));
|
||||||
|
|
||||||
|
// Allocate memory for the slab.
|
||||||
|
constexpr auto AllocateOption = KMemoryManager::EncodeOption(
|
||||||
|
KMemoryManager::Pool::System, KMemoryManager::Direction::FromFront);
|
||||||
|
const PAddr slab_address =
|
||||||
|
kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, AllocateOption);
|
||||||
|
ASSERT(slab_address != 0);
|
||||||
|
|
||||||
|
// Initialize the slabheap.
|
||||||
|
KPageBuffer::InitializeSlabHeap(kernel, system.DeviceMemory().GetPointer<void>(slab_address),
|
||||||
|
slab_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Kernel
|
||||||
|
|
|
@ -33,11 +33,11 @@ struct KSlabResourceCounts {
|
||||||
size_t num_KDebug;
|
size_t num_KDebug;
|
||||||
size_t num_KIoPool;
|
size_t num_KIoPool;
|
||||||
size_t num_KIoRegion;
|
size_t num_KIoRegion;
|
||||||
|
size_t num_KSessionRequestMappings;
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitializeSlabResourceCounts(KernelCore& kernel);
|
void InitializeSlabResourceCounts(KernelCore& kernel);
|
||||||
size_t CalculateTotalSlabHeapSize(const KernelCore& kernel);
|
size_t CalculateTotalSlabHeapSize(const KernelCore& kernel);
|
||||||
void InitializeKPageBufferSlabHeap(Core::System& system);
|
|
||||||
void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout);
|
void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout);
|
||||||
|
|
||||||
} // namespace Kernel::Init
|
} // namespace Kernel::Init
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "core/hle/kernel/k_resource_limit.h"
|
#include "core/hle/kernel/k_resource_limit.h"
|
||||||
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
||||||
#include "core/hle/kernel/k_system_control.h"
|
#include "core/hle/kernel/k_system_control.h"
|
||||||
|
#include "core/hle/kernel/k_system_resource.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/svc_results.h"
|
#include "core/hle/kernel/svc_results.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
@ -49,9 +50,10 @@ KPageTable::KPageTable(Core::System& system_)
|
||||||
KPageTable::~KPageTable() = default;
|
KPageTable::~KPageTable() = default;
|
||||||
|
|
||||||
Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
|
Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
|
||||||
VAddr code_addr, size_t code_size,
|
bool enable_das_merge, bool from_back,
|
||||||
KMemoryBlockSlabManager* mem_block_slab_manager,
|
KMemoryManager::Pool pool, VAddr code_addr,
|
||||||
KMemoryManager::Pool pool) {
|
size_t code_size, KSystemResource* system_resource,
|
||||||
|
KResourceLimit* resource_limit) {
|
||||||
|
|
||||||
const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) {
|
const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) {
|
||||||
return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type);
|
return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type);
|
||||||
|
@ -116,7 +118,9 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
|
||||||
m_address_space_start = start;
|
m_address_space_start = start;
|
||||||
m_address_space_end = end;
|
m_address_space_end = end;
|
||||||
m_is_kernel = false;
|
m_is_kernel = false;
|
||||||
m_memory_block_slab_manager = mem_block_slab_manager;
|
m_memory_block_slab_manager = system_resource->GetMemoryBlockSlabManagerPointer();
|
||||||
|
m_block_info_manager = system_resource->GetBlockInfoManagerPointer();
|
||||||
|
m_resource_limit = resource_limit;
|
||||||
|
|
||||||
// Determine the region we can place our undetermineds in
|
// Determine the region we can place our undetermineds in
|
||||||
VAddr alloc_start{};
|
VAddr alloc_start{};
|
||||||
|
|
|
@ -23,7 +23,10 @@ class System;
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
class KBlockInfoManager;
|
||||||
class KMemoryBlockManager;
|
class KMemoryBlockManager;
|
||||||
|
class KResourceLimit;
|
||||||
|
class KSystemResource;
|
||||||
|
|
||||||
class KPageTable final {
|
class KPageTable final {
|
||||||
public:
|
public:
|
||||||
|
@ -36,9 +39,9 @@ public:
|
||||||
~KPageTable();
|
~KPageTable();
|
||||||
|
|
||||||
Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
|
Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
|
||||||
VAddr code_addr, size_t code_size,
|
bool enable_das_merge, bool from_back, KMemoryManager::Pool pool,
|
||||||
KMemoryBlockSlabManager* mem_block_slab_manager,
|
VAddr code_addr, size_t code_size, KSystemResource* system_resource,
|
||||||
KMemoryManager::Pool pool);
|
KResourceLimit* resource_limit);
|
||||||
|
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
|
@ -74,9 +77,9 @@ public:
|
||||||
KMemoryState state, KMemoryPermission perm,
|
KMemoryState state, KMemoryPermission perm,
|
||||||
PAddr map_addr = 0);
|
PAddr map_addr = 0);
|
||||||
|
|
||||||
Result LockForMapDeviceAddressSpace(VAddr address, size_t size, KMemoryPermission perm,
|
Result LockForMapDeviceAddressSpace(bool* out_is_io, VAddr address, size_t size,
|
||||||
bool is_aligned);
|
KMemoryPermission perm, bool is_aligned, bool check_heap);
|
||||||
Result LockForUnmapDeviceAddressSpace(VAddr address, size_t size);
|
Result LockForUnmapDeviceAddressSpace(VAddr address, size_t size, bool check_heap);
|
||||||
|
|
||||||
Result UnlockForDeviceAddressSpace(VAddr addr, size_t size);
|
Result UnlockForDeviceAddressSpace(VAddr addr, size_t size);
|
||||||
|
|
||||||
|
@ -99,11 +102,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class OperationType : u32 {
|
enum class OperationType : u32 {
|
||||||
Map,
|
Map = 0,
|
||||||
MapGroup,
|
MapFirst = 1,
|
||||||
Unmap,
|
MapGroup = 2,
|
||||||
ChangePermissions,
|
Unmap = 3,
|
||||||
ChangePermissionsAndRefresh,
|
ChangePermissions = 4,
|
||||||
|
ChangePermissionsAndRefresh = 5,
|
||||||
|
Separate = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr KMemoryAttribute DefaultMemoryIgnoreAttr =
|
static constexpr KMemoryAttribute DefaultMemoryIgnoreAttr =
|
||||||
|
@ -199,6 +204,10 @@ private:
|
||||||
return *out != 0;
|
return *out != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HACK: These will be removed once we automatically manage page reference counts.
|
||||||
|
void HACK_OpenPages(PAddr phys_addr, size_t num_pages);
|
||||||
|
void HACK_ClosePages(VAddr virt_addr, size_t num_pages);
|
||||||
|
|
||||||
mutable KLightLock m_general_lock;
|
mutable KLightLock m_general_lock;
|
||||||
mutable KLightLock m_map_physical_memory_lock;
|
mutable KLightLock m_map_physical_memory_lock;
|
||||||
|
|
||||||
|
@ -347,20 +356,27 @@ private:
|
||||||
VAddr m_alias_code_region_start{};
|
VAddr m_alias_code_region_start{};
|
||||||
VAddr m_alias_code_region_end{};
|
VAddr m_alias_code_region_end{};
|
||||||
|
|
||||||
size_t m_mapped_physical_memory_size{};
|
|
||||||
size_t m_max_heap_size{};
|
size_t m_max_heap_size{};
|
||||||
size_t m_max_physical_memory_size{};
|
size_t m_mapped_physical_memory_size{};
|
||||||
|
size_t m_mapped_unsafe_physical_memory{};
|
||||||
|
size_t m_mapped_insecure_memory{};
|
||||||
|
size_t m_mapped_ipc_server_memory{};
|
||||||
size_t m_address_space_width{};
|
size_t m_address_space_width{};
|
||||||
|
|
||||||
KMemoryBlockManager m_memory_block_manager;
|
KMemoryBlockManager m_memory_block_manager;
|
||||||
|
u32 m_allocate_option{};
|
||||||
|
|
||||||
bool m_is_kernel{};
|
bool m_is_kernel{};
|
||||||
bool m_enable_aslr{};
|
bool m_enable_aslr{};
|
||||||
bool m_enable_device_address_space_merge{};
|
bool m_enable_device_address_space_merge{};
|
||||||
|
|
||||||
KMemoryBlockSlabManager* m_memory_block_slab_manager{};
|
KMemoryBlockSlabManager* m_memory_block_slab_manager{};
|
||||||
|
KBlockInfoManager* m_block_info_manager{};
|
||||||
|
KResourceLimit* m_resource_limit{};
|
||||||
|
|
||||||
u32 m_heap_fill_value{};
|
u32 m_heap_fill_value{};
|
||||||
|
u32 m_ipc_fill_value{};
|
||||||
|
u32 m_stack_fill_value{};
|
||||||
const KMemoryRegion* m_cached_physical_heap_region{};
|
const KMemoryRegion* m_cached_physical_heap_region{};
|
||||||
|
|
||||||
KMemoryManager::Pool m_memory_pool{KMemoryManager::Pool::Application};
|
KMemoryManager::Pool m_memory_pool{KMemoryManager::Pool::Application};
|
||||||
|
|
|
@ -358,8 +358,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
|
||||||
}
|
}
|
||||||
// Initialize proces address space
|
// Initialize proces address space
|
||||||
if (const Result result{page_table.InitializeForProcess(
|
if (const Result result{page_table.InitializeForProcess(
|
||||||
metadata.GetAddressSpaceType(), false, 0x8000000, code_size,
|
metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
|
||||||
&kernel.GetApplicationMemoryBlockManager(), KMemoryManager::Pool::Application)};
|
0x8000000, code_size, &kernel.GetSystemSystemResource(), resource_limit)};
|
||||||
result.IsError()) {
|
result.IsError()) {
|
||||||
R_RETURN(result);
|
R_RETURN(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,12 @@
|
||||||
#include "core/hle/kernel/k_handle_table.h"
|
#include "core/hle/kernel/k_handle_table.h"
|
||||||
#include "core/hle/kernel/k_memory_layout.h"
|
#include "core/hle/kernel/k_memory_layout.h"
|
||||||
#include "core/hle/kernel/k_memory_manager.h"
|
#include "core/hle/kernel/k_memory_manager.h"
|
||||||
|
#include "core/hle/kernel/k_page_buffer.h"
|
||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
#include "core/hle/kernel/k_resource_limit.h"
|
#include "core/hle/kernel/k_resource_limit.h"
|
||||||
#include "core/hle/kernel/k_scheduler.h"
|
#include "core/hle/kernel/k_scheduler.h"
|
||||||
#include "core/hle/kernel/k_shared_memory.h"
|
#include "core/hle/kernel/k_shared_memory.h"
|
||||||
|
#include "core/hle/kernel/k_system_resource.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
#include "core/hle/kernel/k_worker_task_manager.h"
|
#include "core/hle/kernel/k_worker_task_manager.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
|
@ -47,6 +49,11 @@ MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70));
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
struct KernelCore::Impl {
|
struct KernelCore::Impl {
|
||||||
|
static constexpr size_t ApplicationMemoryBlockSlabHeapSize = 20000;
|
||||||
|
static constexpr size_t SystemMemoryBlockSlabHeapSize = 10000;
|
||||||
|
static constexpr size_t BlockInfoSlabHeapSize = 4000;
|
||||||
|
static constexpr size_t ReservedDynamicPageCount = 64;
|
||||||
|
|
||||||
explicit Impl(Core::System& system_, KernelCore& kernel_)
|
explicit Impl(Core::System& system_, KernelCore& kernel_)
|
||||||
: time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"},
|
: time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"},
|
||||||
service_thread_barrier{2}, system{system_} {}
|
service_thread_barrier{2}, system{system_} {}
|
||||||
|
@ -72,7 +79,6 @@ struct KernelCore::Impl {
|
||||||
// Initialize kernel memory and resources.
|
// Initialize kernel memory and resources.
|
||||||
InitializeSystemResourceLimit(kernel, system.CoreTiming());
|
InitializeSystemResourceLimit(kernel, system.CoreTiming());
|
||||||
InitializeMemoryLayout();
|
InitializeMemoryLayout();
|
||||||
Init::InitializeKPageBufferSlabHeap(system);
|
|
||||||
InitializeShutdownThreads();
|
InitializeShutdownThreads();
|
||||||
InitializePhysicalCores();
|
InitializePhysicalCores();
|
||||||
InitializePreemption(kernel);
|
InitializePreemption(kernel);
|
||||||
|
@ -82,7 +88,8 @@ struct KernelCore::Impl {
|
||||||
const auto& pt_heap_region = memory_layout->GetPageTableHeapRegion();
|
const auto& pt_heap_region = memory_layout->GetPageTableHeapRegion();
|
||||||
ASSERT(pt_heap_region.GetEndAddress() != 0);
|
ASSERT(pt_heap_region.GetEndAddress() != 0);
|
||||||
|
|
||||||
InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize());
|
InitializeResourceManagers(kernel, pt_heap_region.GetAddress(),
|
||||||
|
pt_heap_region.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterHostThread();
|
RegisterHostThread();
|
||||||
|
@ -263,16 +270,82 @@ struct KernelCore::Impl {
|
||||||
system.CoreTiming().ScheduleLoopingEvent(time_interval, time_interval, preemption_event);
|
system.CoreTiming().ScheduleLoopingEvent(time_interval, time_interval, preemption_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeResourceManagers(VAddr address, size_t size) {
|
void InitializeResourceManagers(KernelCore& kernel, VAddr address, size_t size) {
|
||||||
dynamic_page_manager = std::make_unique<KDynamicPageManager>();
|
// Ensure that the buffer is suitable for our use.
|
||||||
memory_block_heap = std::make_unique<KMemoryBlockSlabHeap>();
|
ASSERT(Common::IsAligned(address, PageSize));
|
||||||
app_memory_block_manager = std::make_unique<KMemoryBlockSlabManager>();
|
ASSERT(Common::IsAligned(size, PageSize));
|
||||||
|
|
||||||
dynamic_page_manager->Initialize(address, size);
|
// Ensure that we have space for our reference counts.
|
||||||
static constexpr size_t ApplicationMemoryBlockSlabHeapSize = 20000;
|
const size_t rc_size =
|
||||||
memory_block_heap->Initialize(dynamic_page_manager.get(),
|
Common::AlignUp(KPageTableSlabHeap::CalculateReferenceCountSize(size), PageSize);
|
||||||
ApplicationMemoryBlockSlabHeapSize);
|
ASSERT(rc_size < size);
|
||||||
app_memory_block_manager->Initialize(nullptr, memory_block_heap.get());
|
size -= rc_size;
|
||||||
|
|
||||||
|
// Initialize the resource managers' shared page manager.
|
||||||
|
resource_manager_page_manager = std::make_unique<KDynamicPageManager>();
|
||||||
|
resource_manager_page_manager->Initialize(
|
||||||
|
address, size, std::max<size_t>(PageSize, KPageBufferSlabHeap::BufferSize));
|
||||||
|
|
||||||
|
// Initialize the KPageBuffer slab heap.
|
||||||
|
page_buffer_slab_heap.Initialize(system);
|
||||||
|
|
||||||
|
// Initialize the fixed-size slabheaps.
|
||||||
|
app_memory_block_heap = std::make_unique<KMemoryBlockSlabHeap>();
|
||||||
|
sys_memory_block_heap = std::make_unique<KMemoryBlockSlabHeap>();
|
||||||
|
block_info_heap = std::make_unique<KBlockInfoSlabHeap>();
|
||||||
|
app_memory_block_heap->Initialize(resource_manager_page_manager.get(),
|
||||||
|
ApplicationMemoryBlockSlabHeapSize);
|
||||||
|
sys_memory_block_heap->Initialize(resource_manager_page_manager.get(),
|
||||||
|
SystemMemoryBlockSlabHeapSize);
|
||||||
|
block_info_heap->Initialize(resource_manager_page_manager.get(), BlockInfoSlabHeapSize);
|
||||||
|
|
||||||
|
// Reserve all but a fixed number of remaining pages for the page table heap.
|
||||||
|
const size_t num_pt_pages = resource_manager_page_manager->GetCount() -
|
||||||
|
resource_manager_page_manager->GetUsed() -
|
||||||
|
ReservedDynamicPageCount;
|
||||||
|
page_table_heap = std::make_unique<KPageTableSlabHeap>();
|
||||||
|
|
||||||
|
// TODO(bunnei): Pass in address once we support kernel virtual memory allocations.
|
||||||
|
page_table_heap->Initialize(
|
||||||
|
resource_manager_page_manager.get(), num_pt_pages,
|
||||||
|
/*GetPointer<KPageTableManager::RefCount>(address + size)*/ nullptr);
|
||||||
|
|
||||||
|
// Setup the slab managers.
|
||||||
|
KDynamicPageManager* const app_dynamic_page_manager = nullptr;
|
||||||
|
KDynamicPageManager* const sys_dynamic_page_manager =
|
||||||
|
/*KTargetSystem::IsDynamicResourceLimitsEnabled()*/ true
|
||||||
|
? resource_manager_page_manager.get()
|
||||||
|
: nullptr;
|
||||||
|
app_memory_block_manager = std::make_unique<KMemoryBlockSlabManager>();
|
||||||
|
sys_memory_block_manager = std::make_unique<KMemoryBlockSlabManager>();
|
||||||
|
app_block_info_manager = std::make_unique<KBlockInfoManager>();
|
||||||
|
sys_block_info_manager = std::make_unique<KBlockInfoManager>();
|
||||||
|
app_page_table_manager = std::make_unique<KPageTableManager>();
|
||||||
|
sys_page_table_manager = std::make_unique<KPageTableManager>();
|
||||||
|
|
||||||
|
app_memory_block_manager->Initialize(app_dynamic_page_manager, app_memory_block_heap.get());
|
||||||
|
sys_memory_block_manager->Initialize(sys_dynamic_page_manager, sys_memory_block_heap.get());
|
||||||
|
|
||||||
|
app_block_info_manager->Initialize(app_dynamic_page_manager, block_info_heap.get());
|
||||||
|
sys_block_info_manager->Initialize(sys_dynamic_page_manager, block_info_heap.get());
|
||||||
|
|
||||||
|
app_page_table_manager->Initialize(app_dynamic_page_manager, page_table_heap.get());
|
||||||
|
sys_page_table_manager->Initialize(sys_dynamic_page_manager, page_table_heap.get());
|
||||||
|
|
||||||
|
// Check that we have the correct number of dynamic pages available.
|
||||||
|
ASSERT(resource_manager_page_manager->GetCount() -
|
||||||
|
resource_manager_page_manager->GetUsed() ==
|
||||||
|
ReservedDynamicPageCount);
|
||||||
|
|
||||||
|
// Create the system page table managers.
|
||||||
|
app_system_resource = std::make_unique<KSystemResource>(kernel);
|
||||||
|
sys_system_resource = std::make_unique<KSystemResource>(kernel);
|
||||||
|
|
||||||
|
// Set the managers for the system resources.
|
||||||
|
app_system_resource->SetManagers(*app_memory_block_manager, *app_block_info_manager,
|
||||||
|
*app_page_table_manager);
|
||||||
|
sys_system_resource->SetManagers(*sys_memory_block_manager, *sys_block_info_manager,
|
||||||
|
*sys_page_table_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeShutdownThreads() {
|
void InitializeShutdownThreads() {
|
||||||
|
@ -767,6 +840,8 @@ struct KernelCore::Impl {
|
||||||
Init::KSlabResourceCounts slab_resource_counts{};
|
Init::KSlabResourceCounts slab_resource_counts{};
|
||||||
KResourceLimit* system_resource_limit{};
|
KResourceLimit* system_resource_limit{};
|
||||||
|
|
||||||
|
KPageBufferSlabHeap page_buffer_slab_heap;
|
||||||
|
|
||||||
std::shared_ptr<Core::Timing::EventType> preemption_event;
|
std::shared_ptr<Core::Timing::EventType> preemption_event;
|
||||||
|
|
||||||
// This is the kernel's handle table or supervisor handle table which
|
// This is the kernel's handle table or supervisor handle table which
|
||||||
|
@ -792,10 +867,20 @@ struct KernelCore::Impl {
|
||||||
// Kernel memory management
|
// Kernel memory management
|
||||||
std::unique_ptr<KMemoryManager> memory_manager;
|
std::unique_ptr<KMemoryManager> memory_manager;
|
||||||
|
|
||||||
// Dynamic slab managers
|
// Resource managers
|
||||||
std::unique_ptr<KDynamicPageManager> dynamic_page_manager;
|
std::unique_ptr<KDynamicPageManager> resource_manager_page_manager;
|
||||||
std::unique_ptr<KMemoryBlockSlabHeap> memory_block_heap;
|
std::unique_ptr<KPageTableSlabHeap> page_table_heap;
|
||||||
|
std::unique_ptr<KMemoryBlockSlabHeap> app_memory_block_heap;
|
||||||
|
std::unique_ptr<KMemoryBlockSlabHeap> sys_memory_block_heap;
|
||||||
|
std::unique_ptr<KBlockInfoSlabHeap> block_info_heap;
|
||||||
|
std::unique_ptr<KPageTableManager> app_page_table_manager;
|
||||||
|
std::unique_ptr<KPageTableManager> sys_page_table_manager;
|
||||||
std::unique_ptr<KMemoryBlockSlabManager> app_memory_block_manager;
|
std::unique_ptr<KMemoryBlockSlabManager> app_memory_block_manager;
|
||||||
|
std::unique_ptr<KMemoryBlockSlabManager> sys_memory_block_manager;
|
||||||
|
std::unique_ptr<KBlockInfoManager> app_block_info_manager;
|
||||||
|
std::unique_ptr<KBlockInfoManager> sys_block_info_manager;
|
||||||
|
std::unique_ptr<KSystemResource> app_system_resource;
|
||||||
|
std::unique_ptr<KSystemResource> sys_system_resource;
|
||||||
|
|
||||||
// Shared memory for services
|
// Shared memory for services
|
||||||
Kernel::KSharedMemory* hid_shared_mem{};
|
Kernel::KSharedMemory* hid_shared_mem{};
|
||||||
|
@ -1073,12 +1158,12 @@ const KMemoryManager& KernelCore::MemoryManager() const {
|
||||||
return *impl->memory_manager;
|
return *impl->memory_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
KMemoryBlockSlabManager& KernelCore::GetApplicationMemoryBlockManager() {
|
KSystemResource& KernelCore::GetSystemSystemResource() {
|
||||||
return *impl->app_memory_block_manager;
|
return *impl->sys_system_resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
const KMemoryBlockSlabManager& KernelCore::GetApplicationMemoryBlockManager() const {
|
const KSystemResource& KernelCore::GetSystemSystemResource() const {
|
||||||
return *impl->app_memory_block_manager;
|
return *impl->sys_system_resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::KSharedMemory& KernelCore::GetHidSharedMem() {
|
Kernel::KSharedMemory& KernelCore::GetHidSharedMem() {
|
||||||
|
|
|
@ -34,13 +34,16 @@ class KClientPort;
|
||||||
class GlobalSchedulerContext;
|
class GlobalSchedulerContext;
|
||||||
class KAutoObjectWithListContainer;
|
class KAutoObjectWithListContainer;
|
||||||
class KClientSession;
|
class KClientSession;
|
||||||
|
class KDebug;
|
||||||
|
class KDynamicPageManager;
|
||||||
class KEvent;
|
class KEvent;
|
||||||
|
class KEventInfo;
|
||||||
class KHandleTable;
|
class KHandleTable;
|
||||||
class KLinkedListNode;
|
class KLinkedListNode;
|
||||||
class KMemoryBlockSlabManager;
|
|
||||||
class KMemoryLayout;
|
class KMemoryLayout;
|
||||||
class KMemoryManager;
|
class KMemoryManager;
|
||||||
class KPageBuffer;
|
class KPageBuffer;
|
||||||
|
class KPageBufferSlabHeap;
|
||||||
class KPort;
|
class KPort;
|
||||||
class KProcess;
|
class KProcess;
|
||||||
class KResourceLimit;
|
class KResourceLimit;
|
||||||
|
@ -50,6 +53,7 @@ class KSession;
|
||||||
class KSessionRequest;
|
class KSessionRequest;
|
||||||
class KSharedMemory;
|
class KSharedMemory;
|
||||||
class KSharedMemoryInfo;
|
class KSharedMemoryInfo;
|
||||||
|
class KSecureSystemResource;
|
||||||
class KThread;
|
class KThread;
|
||||||
class KThreadLocalPage;
|
class KThreadLocalPage;
|
||||||
class KTransferMemory;
|
class KTransferMemory;
|
||||||
|
@ -243,11 +247,11 @@ public:
|
||||||
/// Gets the virtual memory manager for the kernel.
|
/// Gets the virtual memory manager for the kernel.
|
||||||
const KMemoryManager& MemoryManager() const;
|
const KMemoryManager& MemoryManager() const;
|
||||||
|
|
||||||
/// Gets the application memory block manager for the kernel.
|
/// Gets the system resource manager.
|
||||||
KMemoryBlockSlabManager& GetApplicationMemoryBlockManager();
|
KSystemResource& GetSystemSystemResource();
|
||||||
|
|
||||||
/// Gets the application memory block manager for the kernel.
|
/// Gets the system resource manager.
|
||||||
const KMemoryBlockSlabManager& GetApplicationMemoryBlockManager() const;
|
const KSystemResource& GetSystemSystemResource() const;
|
||||||
|
|
||||||
/// Gets the shared memory object for HID services.
|
/// Gets the shared memory object for HID services.
|
||||||
Kernel::KSharedMemory& GetHidSharedMem();
|
Kernel::KSharedMemory& GetHidSharedMem();
|
||||||
|
@ -363,6 +367,12 @@ public:
|
||||||
return slab_heap_container->thread_local_page;
|
return slab_heap_container->thread_local_page;
|
||||||
} else if constexpr (std::is_same_v<T, KSessionRequest>) {
|
} else if constexpr (std::is_same_v<T, KSessionRequest>) {
|
||||||
return slab_heap_container->session_request;
|
return slab_heap_container->session_request;
|
||||||
|
} else if constexpr (std::is_same_v<T, KSecureSystemResource>) {
|
||||||
|
return slab_heap_container->secure_system_resource;
|
||||||
|
} else if constexpr (std::is_same_v<T, KEventInfo>) {
|
||||||
|
return slab_heap_container->event_info;
|
||||||
|
} else if constexpr (std::is_same_v<T, KDebug>) {
|
||||||
|
return slab_heap_container->debug;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,6 +436,9 @@ private:
|
||||||
KSlabHeap<KPageBuffer> page_buffer;
|
KSlabHeap<KPageBuffer> page_buffer;
|
||||||
KSlabHeap<KThreadLocalPage> thread_local_page;
|
KSlabHeap<KThreadLocalPage> thread_local_page;
|
||||||
KSlabHeap<KSessionRequest> session_request;
|
KSlabHeap<KSessionRequest> session_request;
|
||||||
|
KSlabHeap<KSecureSystemResource> secure_system_resource;
|
||||||
|
KSlabHeap<KEventInfo> event_info;
|
||||||
|
KSlabHeap<KDebug> debug;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<SlabHeapContainer> slab_heap_container;
|
std::unique_ptr<SlabHeapContainer> slab_heap_container;
|
||||||
|
|
Loading…
Reference in a new issue