kernel: Implement some functions

This commit is contained in:
IndecisiveTurtle 2024-06-21 18:22:37 +03:00 committed by georgemoralis
parent 7bdaeafdfd
commit 2506a285f4
9 changed files with 69 additions and 12 deletions

View File

@ -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);

View File

@ -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<Core::Linker>::Instance();
linker->SetHeapApiFunc(func);

View File

@ -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

View File

@ -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<Module>(elf_name, max_tls_index);
auto module = std::make_unique<Module>(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;

View File

@ -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<OrbisProcParam*>();
}
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{};

View File

@ -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.

View File

@ -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;

View File

@ -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<void**>(&base_virtual_addr);
memory->MapMemory(out_addr, LoadAddress, aligned_base_size + TrampolineSize,
MemoryProt::CpuReadWrite, MemoryMapFlags::Fixed, VMAType::Code, name, true);

View File

@ -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;