From 2506a285f47a239b3f1420460fe524175a5fea40 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Fri, 21 Jun 2024 18:22:37 +0300 Subject: [PATCH] kernel: Implement some functions --- src/core/libraries/kernel/libkernel.cpp | 3 ++ .../libraries/kernel/memory_management.cpp | 7 ++++ src/core/libraries/kernel/memory_management.h | 1 + src/core/linker.cpp | 10 ++++-- src/core/linker.h | 32 +++++++++++++++++-- src/core/memory.cpp | 6 ++-- src/core/memory.h | 11 ++++++- src/core/module.cpp | 6 ++-- src/core/module.h | 5 ++- 9 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index a4ca5901..bc2717ae 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -298,6 +298,8 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { sceKernelAllocateMainDirectMemory); LIB_FUNCTION("C0f7TJcbfac", "libkernel", 1, "libkernel", 1, 1, sceKernelAvailableDirectMemorySize); + LIB_FUNCTION("hwVSPCmp5tM", "libkernel", 1, "libkernel", 1, 1, + sceKernelCheckedReleaseDirectMemory); LIB_FUNCTION("rVjRvHJ0X6c", "libkernel", 1, "libkernel", 1, 1, sceKernelVirtualQuery); LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize); LIB_FUNCTION("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory); @@ -307,6 +309,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("MBuItvba6z8", "libkernel", 1, "libkernel", 1, 1, sceKernelReleaseDirectMemory); LIB_FUNCTION("cQke9UuBQOk", "libkernel", 1, "libkernel", 1, 1, sceKernelMunmap); LIB_FUNCTION("mL8NDH86iQI", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedFlexibleMemory); + LIB_FUNCTION("aNz11fnnzi4", "libkernel", 1, "libkernel", 1, 1, sceKernelAvailableFlexibleMemorySize); LIB_FUNCTION("IWIBBdTHit4", "libkernel", 1, "libkernel", 1, 1, sceKernelMapFlexibleMemory); LIB_FUNCTION("p5EcQeEeJAE", "libkernel", 1, "libkernel", 1, 1, _sceKernelRtldSetApplicationHeapAPI); diff --git a/src/core/libraries/kernel/memory_management.cpp b/src/core/libraries/kernel/memory_management.cpp index 4683440a..153467a6 100644 --- a/src/core/libraries/kernel/memory_management.cpp +++ b/src/core/libraries/kernel/memory_management.cpp @@ -173,6 +173,13 @@ int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInf return memory->DirectMemoryQuery(offset, flags == 1, query_info); } +s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* out_size) { + auto* memory = Core::Memory::Instance(); + *out_size = memory->GetAvailableFlexibleSize(); + LOG_INFO(Kernel_Vmm, "called size = {:#x}", *out_size); + return ORBIS_OK; +} + void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func) { auto* linker = Common::Singleton::Instance(); linker->SetHeapApiFunc(func); diff --git a/src/core/libraries/kernel/memory_management.h b/src/core/libraries/kernel/memory_management.h index 5fc36199..6e3a0660 100644 --- a/src/core/libraries/kernel/memory_management.h +++ b/src/core/libraries/kernel/memory_management.h @@ -78,6 +78,7 @@ int PS4_SYSV_ABI sceKernelQueryMemoryProtection(void* addr, void** start, void** int PS4_SYSV_ABI sceKernelDirectMemoryQuery(u64 offset, int flags, OrbisQueryInfo* query_info, size_t infoSize); +s32 PS4_SYSV_ABI sceKernelAvailableFlexibleMemorySize(size_t* sizeOut); void PS4_SYSV_ABI _sceKernelRtldSetApplicationHeapAPI(void* func); } // namespace Libraries::Kernel diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 2046af93..15dccb04 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -13,6 +13,7 @@ #include "core/libraries/kernel/memory_management.h" #include "core/libraries/kernel/thread_management.h" #include "core/linker.h" +#include "core/memory.h" #include "core/tls.h" #include "core/virtual_memory.h" @@ -46,7 +47,7 @@ static void RunMainEntry(VAddr addr, EntryParams* params, ExitFunc exit_func) { : "rax", "rsi", "rdi"); } -Linker::Linker() = default; +Linker::Linker() : memory{Memory::Instance()} {} Linker::~Linker() = default; @@ -66,6 +67,11 @@ void Linker::Execute() { Relocate(m.get()); } + // Configure used flexible memory size. + if (u64* flexible_size = GetProcParam()->mem_param->flexible_memory_size) { + memory->SetTotalFlexibleSize(*flexible_size); + } + // Init primary thread. Common::SetCurrentThreadName("GAME_MainThread"); Libraries::Kernel::pthreadInitSelfMainThread(); @@ -98,7 +104,7 @@ s32 Linker::LoadModule(const std::filesystem::path& elf_name) { return -1; } - auto module = std::make_unique(elf_name, max_tls_index); + auto module = std::make_unique(memory, elf_name, max_tls_index); if (!module->IsValid()) { LOG_ERROR(Core_Linker, "Provided file {} is not valid ELF file", elf_name.string()); return -1; diff --git a/src/core/linker.h b/src/core/linker.h index bc12de7d..05484924 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -12,6 +12,33 @@ namespace Core { struct DynamicModuleInfo; class Linker; +class MemoryManager; + +struct OrbisKernelMemParam { + u64 size; + u64* extended_page_table; + u64* flexible_memory_size; + u8* extended_memory_1; + u64* extended_gpu_page_table; + u8* extended_memory_2; + u64* exnteded_cpu_page_table; +}; + +struct OrbisProcParam { + u64 size; + u32 magic; + u32 entry_count; + u64 sdk_version; + char* process_name; + char* main_thread_name; + u32* main_thread_prio; + u32* main_thread_stack_size; + void* libc_param; + OrbisKernelMemParam* mem_param; + void* fs_param; + u32* process_preload_enable; + u64 unknown1; +}; struct EntryParams { int argc; @@ -30,8 +57,8 @@ public: return m_hle_symbols; } - VAddr GetProcParam() const { - return m_modules[0]->GetProcParam(); + OrbisProcParam* GetProcParam() const { + return m_modules[0]->GetProcParam(); } Module* GetModule(s32 index) const { @@ -71,6 +98,7 @@ public: private: const Module* FindExportedModule(const ModuleInfo& m, const LibraryInfo& l); + MemoryManager* memory; std::mutex mutex; u32 dtv_generation_counter{1}; size_t static_tls_size{}; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 21261d2d..58593fd7 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -84,7 +84,7 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M MemoryMapFlags flags, VMAType type, std::string_view name, bool is_exec, PAddr phys_addr, u64 alignment) { std::scoped_lock lk{mutex}; - if (type == VMAType::Flexible && total_flexible_usage + size > 448_MB) { + if (type == VMAType::Flexible && flexible_usage + size > total_flexible_size) { return SCE_KERNEL_ERROR_ENOMEM; } @@ -106,7 +106,7 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M MapVulkanMemory(mapped_addr, size); } if (type == VMAType::Flexible) { - total_flexible_usage += size; + flexible_usage += size; } }; @@ -184,7 +184,7 @@ void MemoryManager::UnmapMemory(VAddr virtual_addr, size_t size) { UnmapVulkanMemory(virtual_addr, size); } if (type == VMAType::Flexible) { - total_flexible_usage -= size; + flexible_usage -= size; } // Mark region as free and attempt to coalesce it with neighbours. diff --git a/src/core/memory.h b/src/core/memory.h index d7ec6fc6..220fa43f 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -124,6 +124,14 @@ public: instance = instance_; } + void SetTotalFlexibleSize(u64 size) { + total_flexible_size = size; + } + + u64 GetAvailableFlexibleSize() const { + return total_flexible_size - flexible_usage; + } + PAddr Allocate(PAddr search_start, PAddr search_end, size_t size, u64 alignment, int memory_type); @@ -195,7 +203,8 @@ private: DMemMap dmem_map; VMAMap vma_map; std::recursive_mutex mutex; - size_t total_flexible_usage{}; + size_t total_flexible_size = 448_MB; + size_t flexible_usage{}; struct MappedMemory { vk::UniqueBuffer buffer; diff --git a/src/core/module.cpp b/src/core/module.cpp index ffb443b3..3b7bdf1f 100644 --- a/src/core/module.cpp +++ b/src/core/module.cpp @@ -55,8 +55,9 @@ static std::string EncodeId(u64 nVal) { return enc; } -Module::Module(const std::filesystem::path& file_, u32& max_tls_index) - : file{file_}, name{file.stem().string()} { +Module::Module(Core::MemoryManager* memory_, + const std::filesystem::path& file_, u32& max_tls_index) + : memory{memory_}, file{file_}, name{file.stem().string()} { elf.Open(file); if (elf.IsElfFile()) { LoadModuleToMemory(max_tls_index); @@ -84,7 +85,6 @@ void Module::LoadModuleToMemory(u32& max_tls_index) { aligned_base_size = Common::AlignUp(base_size, BlockAlign); // Map module segments (and possible TLS trampolines) - auto* memory = Core::Memory::Instance(); void** out_addr = reinterpret_cast(&base_virtual_addr); memory->MapMemory(out_addr, LoadAddress, aligned_base_size + TrampolineSize, MemoryProt::CpuReadWrite, MemoryMapFlags::Fixed, VMAType::Code, name, true); diff --git a/src/core/module.h b/src/core/module.h index d4079c7a..007501f0 100644 --- a/src/core/module.h +++ b/src/core/module.h @@ -137,10 +137,12 @@ struct DynamicModuleInfo { }; using ModuleFunc = int (*)(size_t, const void*); +class MemoryManager; class Module { public: - explicit Module(const std::filesystem::path& file, u32& max_tls_index); + explicit Module(Core::MemoryManager* memory, const std::filesystem::path& file, + u32& max_tls_index); ~Module(); VAddr GetBaseAddress() const noexcept { @@ -220,6 +222,7 @@ public: const LibraryInfo* FindLibrary(std::string_view id); public: + Core::MemoryManager* memory; std::filesystem::path file; std::string name; Loader::Elf elf;