diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_layout.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_layout.hpp index b137ff65e..8fb96c6a3 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_layout.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_layout.hpp @@ -68,12 +68,12 @@ namespace ams::kern { KMemoryRegionType_KernelAutoMap = KMemoryRegionType_Kernel | KMemoryRegionAttr_ShouldKernelMap, - KMemoryRegionType_KernelTemp = 0x31, + KMemoryRegionType_KernelTemp = 0x31, - KMemoryRegionType_KernelCode = 0x19, - KMemoryRegionType_KernelStack = 0x29, - KMemoryRegionType_KernelMisc = 0x49, - KMemoryRegionType_KernelSlab = 0x89, + KMemoryRegionType_KernelCode = 0x19, + KMemoryRegionType_KernelStack = 0x29, + KMemoryRegionType_KernelMisc = 0x49, + KMemoryRegionType_KernelSlab = 0x89, KMemoryRegionType_KernelMiscMainStack = 0xB49, KMemoryRegionType_KernelMiscMappedDevice = 0xD49, @@ -416,6 +416,10 @@ namespace ams::kern { static /* constinit */ inline KMemoryRegionTree s_physical_tree; static /* constinit */ inline KMemoryRegionTree s_virtual_linear_tree; static /* constinit */ inline KMemoryRegionTree s_physical_linear_tree; + private: + static ALWAYS_INLINE auto GetVirtualLinearExtents(const KMemoryRegionTree::DerivedRegionExtents physical) { + return KMemoryRegion(GetInteger(GetLinearVirtualAddress(physical.GetAddress())), physical.GetSize(), 0, KMemoryRegionType_None); + } public: static ALWAYS_INLINE KMemoryRegionAllocator &GetMemoryRegionAllocator() { return s_region_allocator; } static ALWAYS_INLINE KMemoryRegionTree &GetVirtualMemoryRegionTree() { return s_virtual_tree; } @@ -479,10 +483,6 @@ namespace ams::kern { return *GetVirtualLinearMemoryRegionTree().FindContainingRegion(GetInteger(address)); } - static NOINLINE auto GetCarveoutRegionExtents() { - return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionAttr_CarveoutProtected); - } - static NOINLINE std::tuple GetTotalAndKernelMemorySizes() { size_t total_size = 0, kernel_size = 0; for (auto it = GetPhysicalMemoryRegionTree().cbegin(); it != GetPhysicalMemoryRegionTree().cend(); it++) { @@ -497,6 +497,86 @@ namespace ams::kern { } static void InitializeLinearMemoryRegionTrees(KPhysicalAddress aligned_linear_phys_start, KVirtualAddress linear_virtual_start); + + static NOINLINE auto GetKernelRegionExtents() { + return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Kernel); + } + + static NOINLINE auto GetKernelCodeRegionExtents() { + return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelCode); + } + + static NOINLINE auto GetKernelStackRegionExtents() { + return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelStack); + } + + static NOINLINE auto GetKernelMiscRegionExtents() { + return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelMisc); + } + + static NOINLINE auto GetKernelSlabRegionExtents() { + return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelSlab); + } + + static NOINLINE const KMemoryRegion &GetCoreLocalRegion() { + return *GetVirtualMemoryRegionTree().FindFirstRegionByType(KMemoryRegionType_CoreLocal); + } + + static NOINLINE auto GetLinearRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionAttr_LinearMapped); + } + + static NOINLINE auto GetLinearRegionExtents() { + return GetVirtualLinearExtents(GetLinearRegionPhysicalExtents()); + } + + static NOINLINE auto GetCarveoutRegionExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionAttr_CarveoutProtected); + } + + static NOINLINE auto GetKernelRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramKernel); + } + + static NOINLINE auto GetKernelCodeRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramKernelCode); + } + + static NOINLINE auto GetKernelSlabRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramKernelSlab); + } + + static NOINLINE auto GetKernelPageTableHeapRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramKernelPtHeap); + } + + static NOINLINE auto GetKernelInitPageTableRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramKernelInitPt); + } + + static NOINLINE auto GetKernelPoolPartitionRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramPoolPartition); + } + + static NOINLINE auto GetKernelMetadataPoolRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramMetadataPool); + } + + static NOINLINE auto GetKernelSystemPoolRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramSystemPool); + } + + static NOINLINE auto GetKernelSystemNonSecurePoolRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramSystemNonSecurePool); + } + + static NOINLINE auto GetKernelAppletPoolRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramAppletPool); + } + + static NOINLINE auto GetKernelApplicationPoolRegionPhysicalExtents() { + return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_DramApplicationPool); + } }; diff --git a/libraries/libmesosphere/include/mesosphere/kern_kernel.hpp b/libraries/libmesosphere/include/mesosphere/kern_kernel.hpp index b0baa7743..6e6ab05f6 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_kernel.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_kernel.hpp @@ -66,6 +66,7 @@ namespace ams::kern { static NOINLINE void InitializeCoreLocalRegion(s32 core_id); static NOINLINE void InitializeMainAndIdleThreads(s32 core_id); static NOINLINE void InitializeResourceManagers(KVirtualAddress address, size_t size); + static NOINLINE void PrintLayout(); static ALWAYS_INLINE State GetState() { return s_state; } static ALWAYS_INLINE void SetState(State state) { s_state = state; } diff --git a/libraries/libmesosphere/source/kern_kernel.cpp b/libraries/libmesosphere/source/kern_kernel.cpp index 3e397261d..a3020f28b 100644 --- a/libraries/libmesosphere/source/kern_kernel.cpp +++ b/libraries/libmesosphere/source/kern_kernel.cpp @@ -28,6 +28,26 @@ namespace ams::kern { KMemoryBlockSlabManager Kernel::s_sys_memory_block_manager; KBlockInfoManager Kernel::s_block_info_manager; + namespace { + + template + ALWAYS_INLINE void PrintMemoryRegion(const char *prefix, const T &extents) { + static_assert(std::is_same::value); + static_assert(std::is_same::value); + if constexpr (std::is_same::value) { + MESOSPHERE_LOG("%-24s0x%08x - 0x%08x\n", prefix, extents.GetAddress(), extents.GetLastAddress()); + } else if constexpr (std::is_same::value) { + MESOSPHERE_LOG("%-24s0x%016lx - 0x%016lx\n", prefix, extents.GetAddress(), extents.GetLastAddress()); + } else if constexpr (std::is_same::value) { + MESOSPHERE_LOG("%-24s0x%016llx - 0x%016llx\n", prefix, extents.GetAddress(), extents.GetLastAddress()); + } else { + static_assert(!std::is_same::value, "Unknown uintptr_t width!"); + } + + } + + } + void Kernel::InitializeCoreLocalRegion(s32 core_id) { /* Construct the core local region object in place. */ KCoreLocalContext *clc = GetPointer(KMemoryLayout::GetCoreLocalRegionAddress()); @@ -100,4 +120,46 @@ namespace ams::kern { s_page_table_manager.Initialize(address, pt_size, GetPointer(address + pt_size + fixed_size)); } + void Kernel::PrintLayout() { + /* Print out the kernel version. */ + /* TODO: target firmware, if we support that? */ + MESOSPHERE_LOG("Horizon Kernel (Mesosphere)\n"); + MESOSPHERE_LOG("Atmosphere version: %d.%d.%d\n", ATMOSPHERE_RELEASE_VERSION); + MESOSPHERE_LOG("Supported OS version: %d.%d.%d\n", ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR, ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR, ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO); + MESOSPHERE_LOG("\n"); + + /* Print relative memory usage. */ + const auto [total, kernel] = KMemoryLayout::GetTotalAndKernelMemorySizes(); + MESOSPHERE_LOG("Kernel Memory Usage: %zu/%zu MB\n", util::AlignUp(kernel, 1_MB) / 1_MB, util::AlignUp(total, 1_MB) / 1_MB); + MESOSPHERE_LOG("\n"); + + /* Print out important memory layout regions. */ + MESOSPHERE_LOG("Virtual Memory Layout\n"); + PrintMemoryRegion(" KernelRegion", KMemoryLayout::GetKernelRegionExtents()); + PrintMemoryRegion(" Code", KMemoryLayout::GetKernelCodeRegionExtents()); + PrintMemoryRegion(" Stack", KMemoryLayout::GetKernelStackRegionExtents()); + PrintMemoryRegion(" Misc", KMemoryLayout::GetKernelMiscRegionExtents()); + PrintMemoryRegion(" Slab", KMemoryLayout::GetKernelSlabRegionExtents()); + PrintMemoryRegion(" CoreLocalRegion", KMemoryLayout::GetCoreLocalRegion()); + PrintMemoryRegion(" LinearRegion", KMemoryLayout::GetLinearRegionExtents()); + MESOSPHERE_LOG("\n"); + + MESOSPHERE_LOG("Physical Memory Layout\n"); + PrintMemoryRegion(" LinearRegion", KMemoryLayout::GetLinearRegionPhysicalExtents()); + PrintMemoryRegion(" CarveoutRegion", KMemoryLayout::GetCarveoutRegionExtents()); + MESOSPHERE_LOG("\n"); + PrintMemoryRegion(" KernelRegion", KMemoryLayout::GetKernelRegionPhysicalExtents()); + PrintMemoryRegion(" Code", KMemoryLayout::GetKernelCodeRegionPhysicalExtents()); + PrintMemoryRegion(" Slab", KMemoryLayout::GetKernelSlabRegionPhysicalExtents()); + PrintMemoryRegion(" PageTableHeap", KMemoryLayout::GetKernelPageTableHeapRegionPhysicalExtents()); + PrintMemoryRegion(" InitPageTable", KMemoryLayout::GetKernelInitPageTableRegionPhysicalExtents()); + PrintMemoryRegion(" MemoryPoolRegion", KMemoryLayout::GetKernelPoolPartitionRegionPhysicalExtents()); + PrintMemoryRegion(" System", KMemoryLayout::GetKernelSystemPoolRegionPhysicalExtents()); + PrintMemoryRegion(" Internal", KMemoryLayout::GetKernelMetadataPoolRegionPhysicalExtents()); + PrintMemoryRegion(" SystemUnsafe", KMemoryLayout::GetKernelSystemNonSecurePoolRegionPhysicalExtents()); + PrintMemoryRegion(" Applet", KMemoryLayout::GetKernelAppletPoolRegionPhysicalExtents()); + PrintMemoryRegion(" Application", KMemoryLayout::GetKernelApplicationPoolRegionPhysicalExtents()); + MESOSPHERE_LOG("\n"); + } + } diff --git a/libraries/libmesosphere/source/kern_main.cpp b/libraries/libmesosphere/source/kern_main.cpp index f54f76492..4157f86ad 100644 --- a/libraries/libmesosphere/source/kern_main.cpp +++ b/libraries/libmesosphere/source/kern_main.cpp @@ -59,6 +59,9 @@ namespace ams::kern { /* Copy the Initial Process Binary to safe memory. */ CopyInitialProcessBinaryToKernelMemory(); + /* Print out information about the kernel. */ + Kernel::PrintLayout(); + /* Initialize the KObject Slab Heaps. */ init::InitializeSlabHeaps();