diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp index f2c39edf4..d43eaeb15 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp @@ -277,6 +277,16 @@ namespace ams::kern::arm64::cpu { } }; + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(SystemControl) { + public: + MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS_FUNCTIONS(SystemControl, sctlr_el1) + + constexpr ALWAYS_INLINE decltype(auto) SetWxn(bool en) { + this->SetBit(19, en); + return *this; + } + }; + /* Accessors for timer registers. */ MESOSPHERE_CPU_SYSREG_ACCESSOR_CLASS(CounterTimerKernelControl) { public: diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index 9fdc66164..003691f4e 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -34,7 +34,7 @@ namespace ams::kern::arm64 { static NOINLINE void Initialize(s32 core_id); - Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); + NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); Result Finalize(); }; diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp index 671b967a6..d92315ab3 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp @@ -34,7 +34,7 @@ namespace ams::kern::arm64 { public: constexpr KPageTableImpl() : table(), is_kernel(), num_entries() { /* ... */ } - void InitializeForKernel(void *tb, KVirtualAddress start, KVirtualAddress end); + NOINLINE void InitializeForKernel(void *tb, KVirtualAddress start, KVirtualAddress end); u64 *Finalize(); }; diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp index 02f435f86..9c4425bad 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp @@ -27,7 +27,7 @@ namespace ams::kern::arm64 { public: constexpr KSupervisorPageTable() : page_table(), ttbr0() { /* ... */ } - void Initialize(s32 core_id); + NOINLINE void Initialize(s32 core_id); void Finalize(s32 core_id); }; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 33ca66932..c4fa8b689 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -26,14 +26,61 @@ namespace ams::kern { class KPageTableBase { NON_COPYABLE(KPageTableBase); NON_MOVEABLE(KPageTableBase); + protected: + enum MemoryFillValue { + MemoryFillValue_Zero = 0, + MemoryFillValue_Stack = 'X', + MemoryFillValue_Ipc = 'Y', + MemoryFillValue_Heap = 'Z', + }; private: - /* TODO: All other members. */ - /* There are a substantial number of them. */ + KProcessAddress address_space_start; + KProcessAddress address_space_end; + KProcessAddress heap_region_start; + KProcessAddress heap_region_end; + KProcessAddress current_heap_end; + KProcessAddress alias_region_start; + KProcessAddress alias_region_end; + KProcessAddress stack_region_start; + KProcessAddress stack_region_end; + KProcessAddress kernel_map_region_start; + KProcessAddress kernel_map_region_end; + KProcessAddress alias_code_region_start; + KProcessAddress alias_code_region_end; + KProcessAddress code_region_start; + KProcessAddress code_region_end; + size_t max_heap_size; + size_t max_physical_memory_size; + mutable KLightLock general_lock; + mutable KLightLock map_physical_memory_lock; KPageTableImpl impl; + /* TODO KMemoryBlockManager memory_block_manager; */ + u32 allocate_option; + u32 address_space_size; + bool is_kernel; + bool enable_aslr; + KMemoryBlockSlabManager *memory_block_slab_manager; + KBlockInfoManager *block_info_manager; + KMemoryRegion *cached_physical_linear_region; + KMemoryRegion *cached_physical_non_kernel_dram_region; + KMemoryRegion *cached_virtual_managed_pool_dram_region; + MemoryFillValue heap_fill_value; + MemoryFillValue ipc_fill_value; + MemoryFillValue stack_fill_value; public: - constexpr KPageTableBase() : impl() { /* ... */ } + constexpr KPageTableBase() : + address_space_start(), address_space_end(), heap_region_start(), heap_region_end(), current_heap_end(), + alias_region_start(), alias_region_end(), stack_region_start(), stack_region_end(), kernel_map_region_start(), + kernel_map_region_end(), alias_code_region_start(), alias_code_region_end(), code_region_start(), code_region_end(), + max_heap_size(), max_physical_memory_size(), general_lock(), map_physical_memory_lock(), impl(), /* TODO: memory_block_manager(), */ + allocate_option(), address_space_size(), is_kernel(), enable_aslr(), memory_block_slab_manager(), block_info_manager(), + cached_physical_linear_region(), cached_physical_non_kernel_dram_region(), cached_virtual_managed_pool_dram_region(), + heap_fill_value(), ipc_fill_value(), stack_fill_value() + { + /* ... */ + } - Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end); + NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end); void Finalize(); public: diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp index 07bd400ef..d491e1492 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp @@ -22,12 +22,11 @@ namespace ams::kern::arm64 { this->ttbr0[core_id] = cpu::GetTtbr0El1(); /* Set sctlr_el1 */ - MESOSPHERE_TODO("Set bit in SCTLR_EL1"); + cpu::SystemControlRegisterAccessor().SetWxn(true).Store(); cpu::EnsureInstructionConsistency(); /* Invalidate the entire TLB. */ cpu::InvalidateEntireTlb(); - cpu::EnsureInstructionConsistency(); /* If core 0, initialize our base page table. */ if (core_id == 0) { diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 3c48501ce..5d90f26fe 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -19,11 +19,43 @@ namespace ams::kern { Result KPageTableBase::InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end) { - /* Initialize impl table. */ - this->impl.InitializeForKernel(table, start, end); - /* Initialize our members. */ - MESOSPHERE_TODO("KPageTableBase member initialization"); + this->address_space_size = (is_64_bit) ? BITSIZEOF(u64) : BITSIZEOF(u32); + this->address_space_start = KProcessAddress(GetInteger(start)); + this->address_space_end = KProcessAddress(GetInteger(end)); + this->is_kernel = true; + this->enable_aslr = true; + + this->heap_region_start = 0; + this->heap_region_end = 0; + this->current_heap_end = 0; + this->alias_region_start = 0; + this->alias_region_end = 0; + this->stack_region_start = 0; + this->stack_region_end = 0; + this->kernel_map_region_start = 0; + this->kernel_map_region_end = 0; + this->alias_code_region_start = 0; + this->alias_code_region_end = 0; + this->code_region_start = 0; + this->code_region_end = 0; + this->max_heap_size = 0; + this->max_physical_memory_size = 0; + + this->memory_block_slab_manager = std::addressof(Kernel::GetSystemMemoryBlockManager()); + this->block_info_manager = std::addressof(Kernel::GetBlockInfoManager()); + + this->allocate_option = KMemoryManager::EncodeOption(KMemoryManager::Pool_System, KMemoryManager::Direction_FromFront); + this->heap_fill_value = MemoryFillValue_Zero; + this->ipc_fill_value = MemoryFillValue_Zero; + this->stack_fill_value = MemoryFillValue_Zero; + + this->cached_physical_linear_region = nullptr; + this->cached_physical_non_kernel_dram_region = nullptr; + this->cached_virtual_managed_pool_dram_region = nullptr; + + /* Initialize our implementation. */ + this->impl.InitializeForKernel(table, start, end); /* Initialize our memory block manager. */ MESOSPHERE_TODO("R_TRY(this->memory_block_manager.Initialize(this->address_space_start, this->address_space_end, this->GetMemoryBlockSlabManager()));");