memory: Address some alignment issues

This commit is contained in:
IndecisiveTurtle 2024-07-25 15:46:53 +03:00
parent 3b45003468
commit f24ef13709
7 changed files with 36 additions and 9 deletions

View File

@ -6,7 +6,7 @@
#include "common/bit_field.h"
#include "common/types.h"
constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 5376_MB; // ~ 6GB
constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 6_GB; // ~ 6GB
namespace Libraries::Kernel {

View File

@ -1364,6 +1364,11 @@ int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) {
UNREACHABLE();
}
[[noreturn]] void PS4_SYSV_ABI posix_pthread_exit(void* value_ptr) {
pthread_exit(value_ptr);
UNREACHABLE();
}
int PS4_SYSV_ABI scePthreadGetthreadid() {
return (int)(size_t)g_pthread_self;
}
@ -1415,6 +1420,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, scePthreadDetach);
LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, scePthreadEqual);
LIB_FUNCTION("3kg7rT0NQIs", "libkernel", 1, "libkernel", 1, 1, scePthreadExit);
LIB_FUNCTION("FJrT5LuUBAU", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_exit);
LIB_FUNCTION("7Xl257M4VNI", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_equal);
LIB_FUNCTION("h9CcP3J0oVM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_join);
LIB_FUNCTION("EI-5-jlq2dE", "libkernel", 1, "libkernel", 1, 1, scePthreadGetthreadid);

View File

@ -8,8 +8,6 @@
#include "playgo.h"
namespace Libraries::PlayGo {
// this lib is used to play as the game is being installed.
// can be skipped by just returning and assigning the correct values.
s32 PS4_SYSV_ABI sceDbgPlayGoRequestNextChunk() {
LOG_ERROR(Lib_PlayGo, "(STUBBED)called");
@ -141,4 +139,4 @@ void RegisterlibScePlayGo(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("MPe0EeBGM-E", "libScePlayGo", 1, "libScePlayGo", 1, 0, scePlayGoTerminate);
};
} // namespace Libraries::PlayGo
} // namespace Libraries::PlayGo

View File

@ -320,11 +320,15 @@ void Linker::InitTlsForThread(bool is_primary) {
static constexpr size_t TlsAllocAlign = 0x20;
const size_t total_tls_size = Common::AlignUp(static_tls_size, TlsAllocAlign) + TcbSize;
// If sceKernelMapNamedFlexibleMemory is being called from libkernel and addr = 0
// it automatically places mappings in system reserved area instead of managed.
static constexpr VAddr KernelAllocBase = 0x880000000ULL;
// The kernel module has a few different paths for TLS allocation.
// For SDK < 1.7 it allocates both main and secondary thread blocks using libc mspace/malloc.
// In games compiled with newer SDK, the main thread gets mapped from flexible memory,
// with addr = 0, so system managed area. Here we will only implement the latter.
void* addr_out{};
void* addr_out{reinterpret_cast<void*>(KernelAllocBase)};
if (is_primary) {
const size_t tls_aligned = Common::AlignUp(total_tls_size, 16_KB);
const int ret = Libraries::Kernel::sceKernelMapNamedFlexibleMemory(

View File

@ -234,6 +234,7 @@ void MemoryManager::UnmapMemory(VAddr virtual_addr, size_t size) {
vma.type = VMAType::Free;
vma.prot = MemoryProt::NoAccess;
vma.phys_base = 0;
vma.disallow_merge = false;
MergeAdjacent(vma_map, new_it);
// Unmap the memory region.
@ -344,11 +345,23 @@ VAddr MemoryManager::SearchFree(VAddr virtual_addr, size_t size, u32 alignment)
return virtual_addr;
}
// Search for the first free VMA that fits our mapping.
while (!it->second.IsFree() || it->second.size < size) {
const auto is_suitable = [&] {
if (!it->second.IsFree()) {
return false;
}
const auto& vma = it->second;
virtual_addr = Common::AlignUp(vma.base, alignment);
// Sometimes the alignment itself might be larger than the VMA.
if (virtual_addr > vma.base + vma.size) {
return false;
}
const size_t remaining_size = vma.base + vma.size - virtual_addr;
return remaining_size >= size;
};
while (!is_suitable()) {
it++;
}
const auto& vma = it->second;
return alignment > 0 ? Common::AlignUp(vma.base, alignment) : vma.base;
return virtual_addr;
}
MemoryManager::VMAHandle MemoryManager::CarveVMA(VAddr virtual_addr, size_t size) {

View File

@ -150,10 +150,12 @@ void Emulator::Run(const std::filesystem::path& file) {
}
void Emulator::LoadSystemModules(const std::filesystem::path& file) {
constexpr std::array<SysModules, 8> ModulesToLoad{
constexpr std::array<SysModules, 10> ModulesToLoad{
{{"libSceNgs2.sprx", nullptr},
{"libSceFiber.sprx", nullptr},
{"libSceUlt.sprx", nullptr},
{"libSceJson.sprx", nullptr},
{"libSceJson2.sprx", nullptr},
{"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterlibSceLibcInternal},
{"libSceDiscMap.sprx", &Libraries::DiscMap::RegisterlibSceDiscMap},
{"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc},

View File

@ -388,6 +388,10 @@ spv::ImageFormat GetFormat(const AmdGpu::Image& image) {
image.GetNumberFmt() == AmdGpu::NumberFormat::Unorm) {
return spv::ImageFormat::Rgba8;
}
if (image.GetDataFmt() == AmdGpu::DataFormat::Format8_8_8_8 &&
image.GetNumberFmt() == AmdGpu::NumberFormat::Uint) {
return spv::ImageFormat::Rgba8ui;
}
UNREACHABLE();
}