Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/Xphalnos/shadPS4
Browse files Browse the repository at this point in the history
  • Loading branch information
Xphalnos committed Jun 14, 2024
2 parents eb22704 + 1a26983 commit edf6724
Show file tree
Hide file tree
Showing 26 changed files with 519 additions and 99 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ set(PAD_LIB src/core/libraries/pad/pad.cpp
src/core/libraries/pad/pad.h
)

set(PNG_LIB src/core/libraries/libpng/pngdec.cpp
src/core/libraries/libpng/pngdec.h
)

set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
src/core/libraries/np_manager/np_manager.h
src/core/libraries/np_score/np_score.cpp
Expand Down Expand Up @@ -290,6 +294,7 @@ set(CORE src/core/aerolib/stubs.cpp
${PAD_LIB}
${VIDEOOUT_LIB}
${NP_LIBS}
${PNG_LIB}
${MISC_LIBS}
src/core/linker.cpp
src/core/linker.h
Expand Down
4 changes: 0 additions & 4 deletions src/audio_core/sdl_audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@

namespace Audio {

int SDLAudio::AudioInit() {
return SDL_InitSubSystem(SDL_INIT_AUDIO);
}

int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq,
Libraries::AudioOut::OrbisAudioOutParam format) {
using Libraries::AudioOut::OrbisAudioOutParam;
Expand Down
1 change: 0 additions & 1 deletion src/audio_core/sdl_audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class SDLAudio {
SDLAudio() = default;
virtual ~SDLAudio() = default;

int AudioInit();
int AudioOutOpen(int type, u32 samples_num, u32 freq,
Libraries::AudioOut::OrbisAudioOutParam format);
s32 AudioOutOutput(s32 handle, const void* ptr);
Expand Down
5 changes: 2 additions & 3 deletions src/common/io_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,8 @@ void IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, File
#endif

if (!IsOpen()) {
const auto ec = std::error_code{errno, std::generic_category()};
LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, ec_message={}",
PathToUTF8String(file_path), ec.message());
LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}",
PathToUTF8String(file_path));
}
}

Expand Down
1 change: 1 addition & 0 deletions src/common/logging/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, AppContent) \
SUB(Lib, Rtc) \
SUB(Lib, DiscMap) \
SUB(Lib, Png) \
CLS(Frontend) \
CLS(Render) \
SUB(Render, Vulkan) \
Expand Down
1 change: 1 addition & 0 deletions src/common/logging/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ enum class Class : u8 {
Lib_AppContent, ///< The LibSceAppContent implementation.
Lib_Rtc, ///< The LibSceRtc implementation.
Lib_DiscMap, ///< The LibSceDiscMap implementation.
Lib_Png, ///< The LibScePng implementation.
Frontend, ///< Emulator UI
Render, ///< Video Core
Render_Vulkan, ///< Vulkan backend
Expand Down
3 changes: 0 additions & 3 deletions src/common/path_util.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include <algorithm>
#include <sstream>
#include <unordered_map>

#include "common/logging/log.h"
#include "common/path_util.h"

Expand Down
82 changes: 77 additions & 5 deletions src/core/address_space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#ifdef _WIN32
#include <windows.h>
#else
#include <fcntl.h>
#include <sys/mman.h>
#endif

Expand Down Expand Up @@ -215,25 +216,96 @@ enum PosixPageProtection {

struct AddressSpace::Impl {
Impl() {
UNREACHABLE();
// Allocate virtual address placeholder for our address space.
void* hint_address = reinterpret_cast<void*>(SYSTEM_MANAGED_MIN);
virtual_size = SystemSize + UserSize;
virtual_base = reinterpret_cast<u8*>(
mmap(reinterpret_cast<void*>(hint_address), virtual_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0));
if (virtual_base == MAP_FAILED) {
LOG_CRITICAL(Kernel_Vmm, "mmap failed: {}", strerror(errno));
throw std::bad_alloc{};
}
madvise(virtual_base, virtual_size, MADV_HUGEPAGE);

backing_fd = memfd_create("BackingDmem", 0);
if (backing_fd < 0) {
LOG_CRITICAL(Kernel_Vmm, "memfd_create failed: {}", strerror(errno));
throw std::bad_alloc{};
}

// Defined to extend the file with zeros
int ret = ftruncate(backing_fd, BackingSize);
if (ret != 0) {
LOG_CRITICAL(Kernel_Vmm, "ftruncate failed with {}, are you out-of-memory?",
strerror(errno));
throw std::bad_alloc{};
}

// Map backing dmem handle.
backing_base = static_cast<u8*>(
mmap(nullptr, BackingSize, PROT_READ | PROT_WRITE, MAP_SHARED, backing_fd, 0));
if (backing_base == MAP_FAILED) {
LOG_CRITICAL(Kernel_Vmm, "mmap failed: {}", strerror(errno));
throw std::bad_alloc{};
}

const VAddr start_addr = reinterpret_cast<VAddr>(virtual_base);
m_free_regions.insert({start_addr, start_addr + virtual_size});
}

void* Map(VAddr virtual_addr, PAddr phys_addr, size_t size, PosixPageProtection prot) {
UNREACHABLE();
return nullptr;
m_free_regions.subtract({virtual_addr, virtual_addr + size});
const int fd = phys_addr != -1 ? backing_fd : -1;
const int host_offset = phys_addr != -1 ? phys_addr : 0;
const int flag = phys_addr != -1 ? MAP_SHARED : (MAP_ANONYMOUS | MAP_PRIVATE);
void* ret = mmap(reinterpret_cast<void*>(virtual_addr), size, prot, MAP_FIXED | flag, fd,
host_offset);
ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
return ret;
}

void Unmap(VAddr virtual_addr, PAddr phys_addr, size_t size) {
UNREACHABLE();
// Check to see if we are adjacent to any regions.
auto start_address = virtual_addr;
auto end_address = start_address + size;
auto it = m_free_regions.find({start_address - 1, end_address + 1});

// If we are, join with them, ensuring we stay in bounds.
if (it != m_free_regions.end()) {
start_address = std::min(start_address, it->lower());
end_address = std::max(end_address, it->upper());
}

// Free the relevant region.
m_free_regions.insert({start_address, end_address});

// Return the adjusted pointers.
void* ret = mmap(reinterpret_cast<void*>(start_address), end_address - start_address,
PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
}

void Protect(VAddr virtual_addr, size_t size, bool read, bool write, bool execute) {
UNREACHABLE();
int flags = PROT_NONE;
if (read) {
flags |= PROT_READ;
}
if (write) {
flags |= PROT_WRITE;
}
if (execute) {
flags |= PROT_EXEC;
}
int ret = mprotect(reinterpret_cast<void*>(virtual_addr), size, flags);
ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno));
}

int backing_fd;
u8* backing_base{};
u8* virtual_base{};
size_t virtual_size{};
boost::icl::interval_set<VAddr> m_free_regions;
};
#endif

Expand Down
5 changes: 2 additions & 3 deletions src/core/file_format/pkg.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include <fstream>
#include <zlib-ng.h>
#include "common/io_file.h"
#include "pkg.h"
#include "pkg_type.h"
#include "core/file_format/pkg.h"
#include "core/file_format/pkg_type.h"

static void DecompressPFSC(std::span<const char> compressed_data,
std::span<char> decompressed_data) {
Expand Down
1 change: 0 additions & 1 deletion src/core/file_format/pkg.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#pragma once

#include <array>
#include <cstdio>
#include <filesystem>
#include <string>
#include <unordered_map>
Expand Down
5 changes: 1 addition & 4 deletions src/core/file_format/psf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later

#include <cstring>
#include <fstream>
#include <iostream>

#include "common/io_file.h"
#include "psf.h"
#include "core/file_format/psf.h"

PSF::PSF() = default;

Expand Down
5 changes: 2 additions & 3 deletions src/core/libraries/audio/audioout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,8 @@ int PS4_SYSV_ABI sceAudioOutGetSystemState() {

int PS4_SYSV_ABI sceAudioOutInit() {
audio = std::make_unique<Audio::SDLAudio>();
u32 result = audio->AudioInit() == 0 ? ORBIS_OK : ORBIS_AUDIO_OUT_ERROR_NOT_INIT;
LOG_INFO(Lib_AudioOut, "AudioInit returned {}", result);
return result;
LOG_INFO(Lib_AudioOut, "called");
return ORBIS_OK;
}

int PS4_SYSV_ABI sceAudioOutInitIpmiGetSession() {
Expand Down
28 changes: 24 additions & 4 deletions src/core/libraries/kernel/thread_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ void* createMutex(void* addr) {
if (addr == nullptr || *static_cast<ScePthreadMutex*>(addr) != nullptr) {
return addr;
}
static std::mutex mutex;
std::scoped_lock lk{mutex};
auto vaddr = reinterpret_cast<u64>(addr);

std::string name = fmt::format("mutex{:#x}", vaddr);
Expand Down Expand Up @@ -464,7 +466,7 @@ int PS4_SYSV_ABI scePthreadMutexattrInit(ScePthreadMutexattr* attr) {

int result = pthread_mutexattr_init(&(*attr)->pth_mutex_attr);

result = (result == 0 ? scePthreadMutexattrSettype(attr, 1) : result);
result = (result == 0 ? scePthreadMutexattrSettype(attr, 2) : result);
result = (result == 0 ? scePthreadMutexattrSetprotocol(attr, 0) : result);

switch (result) {
Expand Down Expand Up @@ -677,7 +679,7 @@ int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex*
time.tv_nsec = ((usec % 1000000) * 1000);
int result = pthread_cond_timedwait(&(*cond)->cond, &(*mutex)->pth_mutex, &time);

LOG_INFO(Kernel_Pthread, "scePthreadCondTimedwait, result={}", result);
// LOG_INFO(Kernel_Pthread, "scePthreadCondTimedwait, result={}", result);

switch (result) {
case 0:
Expand Down Expand Up @@ -1016,7 +1018,7 @@ int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) {

int result = pthread_cond_signal(&(*cond)->cond);

LOG_INFO(Kernel_Pthread, "scePthreadCondSignal, result={}", result);
// LOG_INFO(Kernel_Pthread, "scePthreadCondSignal, result={}", result);

switch (result) {
case 0:
Expand Down Expand Up @@ -1165,6 +1167,22 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(ScePthread* thread, const ScePthre
return result;
}

int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) {
return pthread_once(reinterpret_cast<pthread_once_t*>(once_control), init_routine);
}
int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* attr,
pthreadEntryFunc start_routine, void* arg) {
LOG_INFO(Kernel_Pthread, "posix pthread_create redirect to scePthreadCreate");

int result = scePthreadCreate(thread, attr, start_routine, arg, "");
if (result != 0) {
int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP
? result + -SCE_KERNEL_ERROR_UNKNOWN
: POSIX_EOTHER;
return rt;
}
return result;
}
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy);
LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate);
Expand All @@ -1186,11 +1204,13 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGet);
LIB_FUNCTION("UTXzJbWhhTE", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetstacksize);
LIB_FUNCTION("vNe1w4diLCs", "libkernel", 1, "libkernel", 1, 1, __tls_get_addr);

LIB_FUNCTION("OxhIB8LB-PQ", "libkernel", 1, "libkernel", 1, 1, posix_pthread_create);
LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create);
LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, scePthreadSetaffinity);
LIB_FUNCTION("6UgtwV+0zb4", "libkernel", 1, "libkernel", 1, 1, scePthreadCreate);
LIB_FUNCTION("T72hz6ffq08", "libkernel", 1, "libkernel", 1, 1, scePthreadYield);
LIB_FUNCTION("-quPa4SEJUw", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGetstack);
LIB_FUNCTION("14bOACANTBo", "libkernel", 1, "libkernel", 1, 1, scePthreadOnce);

// mutex calls
LIB_FUNCTION("cmo1RIYva9o", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexInit);
Expand Down
6 changes: 3 additions & 3 deletions src/core/libraries/kernel/thread_management.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct PthreadMutexattrInternal;
struct PthreadCondInternal;
struct PthreadCondAttrInternal;
struct PthreadRwInternal;
struct PthreadRwLockAttrInernal;
struct PthreadRwLockAttrInternal;

using SceKernelSchedParam = ::sched_param;
using ScePthread = PthreadInternal*;
Expand All @@ -37,7 +37,7 @@ using ScePthreadMutexattr = PthreadMutexattrInternal*;
using ScePthreadCond = PthreadCondInternal*;
using ScePthreadCondattr = PthreadCondAttrInternal*;
using OrbisPthreadRwlock = PthreadRwInternal*;
using OrbisPthreadRwlockattr = PthreadRwLockAttrInernal*;
using OrbisPthreadRwlockattr = PthreadRwLockAttrInternal*;

using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);

Expand Down Expand Up @@ -86,7 +86,7 @@ struct PthreadCondAttrInternal {
pthread_condattr_t cond_attr;
};

struct PthreadRwLockAttrInernal {
struct PthreadRwLockAttrInternal {
u8 reserved[64];
pthread_rwlockattr_t attr_rwlock;
int type;
Expand Down
4 changes: 2 additions & 2 deletions src/core/libraries/kernel/threads/kernel_threads_rwlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ int PS4_SYSV_ABI posix_pthread_rwlockattr_gettype_np() {
}

int PS4_SYSV_ABI posix_pthread_rwlockattr_init(OrbisPthreadRwlockattr* attr) {
*attr = new PthreadRwLockAttrInernal{};
*attr = new PthreadRwLockAttrInternal{};
int result = pthread_rwlockattr_init(&(*attr)->attr_rwlock);
if (result != 0) {
LOG_ERROR(Kernel_Pthread, "posix_pthread_rwlockattr_init: error = {}", result);
Expand Down Expand Up @@ -161,7 +161,7 @@ int PS4_SYSV_ABI scePthreadRwlockattrGettype() {
}

int PS4_SYSV_ABI scePthreadRwlockattrInit(OrbisPthreadRwlockattr* attr) {
*attr = new PthreadRwLockAttrInernal{};
*attr = new PthreadRwLockAttrInternal{};
int result = pthread_rwlockattr_init(&(*attr)->attr_rwlock);
if (result != 0) {
LOG_ERROR(Kernel_Pthread, "scePthreadRwlockattrInit: error = {}", result);
Expand Down
Loading

0 comments on commit edf6724

Please sign in to comment.