mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-15 13:21:14 +00:00
PSP2
This commit is contained in:
parent
5c52521a0a
commit
38c444cfa1
@ -1 +0,0 @@
|
||||
#pragma once
|
@ -99,8 +99,8 @@ static const char* fmt_reg(u32 reg)
|
||||
|
||||
static std::string fmt_shift(u32 type, u32 amount)
|
||||
{
|
||||
Expects(type != arm_code::SRType_RRX || amount == 1);
|
||||
Expects(amount <= 32);
|
||||
EXPECTS(type != arm_code::SRType_RRX || amount == 1);
|
||||
EXPECTS(amount <= 32);
|
||||
|
||||
if (amount)
|
||||
{
|
@ -669,7 +669,7 @@ void arm_interpreter::LDM(ARMv7Thread& cpu, const u32 op, const u32 cond)
|
||||
|
||||
if (ConditionPassed(cpu, cond))
|
||||
{
|
||||
vm::ptr<u32> memory(cpu.read_gpr(n), vm::addr);
|
||||
vm::ptr<u32> memory(vm::cast(cpu.read_gpr(n)));
|
||||
|
||||
for (u32 i = 0; i < 16; i++)
|
||||
{
|
||||
@ -1384,7 +1384,7 @@ void arm_interpreter::PUSH(ARMv7Thread& cpu, const u32 op, const u32 cond)
|
||||
|
||||
if (ConditionPassed(cpu, cond))
|
||||
{
|
||||
vm::ptr<u32> memory(cpu.SP, vm::addr);
|
||||
vm::ptr<u32> memory(vm::cast(cpu.SP));
|
||||
|
||||
for (u32 i = 15; ~i; i--)
|
||||
{
|
@ -48,46 +48,46 @@ struct arm_interpreter
|
||||
|
||||
static u32 LSL_C(u32 x, s32 shift, bool& carry_out)
|
||||
{
|
||||
Expects(shift > 0);
|
||||
EXPECTS(shift > 0);
|
||||
carry_out = shift <= 32 ? (x & (1 << (32 - shift))) != 0 : false;
|
||||
return shift < 32 ? x << shift : 0;
|
||||
}
|
||||
|
||||
static u32 LSL_(u32 x, s32 shift)
|
||||
{
|
||||
Expects(shift >= 0);
|
||||
EXPECTS(shift >= 0);
|
||||
return shift < 32 ? x << shift : 0;
|
||||
}
|
||||
|
||||
static u32 LSR_C(u32 x, s32 shift, bool& carry_out)
|
||||
{
|
||||
Expects(shift > 0);
|
||||
EXPECTS(shift > 0);
|
||||
carry_out = shift <= 32 ? (x & (1 << (shift - 1))) != 0 : false;
|
||||
return shift < 32 ? x >> shift : 0;
|
||||
}
|
||||
|
||||
static u32 LSR_(u32 x, s32 shift)
|
||||
{
|
||||
Expects(shift >= 0);
|
||||
EXPECTS(shift >= 0);
|
||||
return shift < 32 ? x >> shift : 0;
|
||||
}
|
||||
|
||||
static s32 ASR_C(s32 x, s32 shift, bool& carry_out)
|
||||
{
|
||||
Expects(shift > 0);
|
||||
EXPECTS(shift > 0);
|
||||
carry_out = shift <= 32 ? (x & (1 << (shift - 1))) != 0 : x < 0;
|
||||
return shift < 32 ? x >> shift : x >> 31;
|
||||
}
|
||||
|
||||
static s32 ASR_(s32 x, s32 shift)
|
||||
{
|
||||
Expects(shift >= 0);
|
||||
EXPECTS(shift >= 0);
|
||||
return shift < 32 ? x >> shift : x >> 31;
|
||||
}
|
||||
|
||||
static u32 ROR_C(u32 x, s32 shift, bool& carry_out)
|
||||
{
|
||||
Expects(shift);
|
||||
EXPECTS(shift);
|
||||
const u32 result = x >> shift | x << (32 - shift);
|
||||
carry_out = (result >> 31) != 0;
|
||||
return result;
|
||||
@ -111,7 +111,7 @@ struct arm_interpreter
|
||||
|
||||
static u32 Shift_C(u32 value, u32 type, s32 amount, bool carry_in, bool& carry_out)
|
||||
{
|
||||
Expects(type != arm_code::SRType_RRX || amount == 1);
|
||||
EXPECTS(type != arm_code::SRType_RRX || amount == 1);
|
||||
|
||||
if (amount)
|
||||
{
|
@ -1,4 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/Config.h"
|
||||
#include "Loader/ELF.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
@ -9,6 +10,67 @@
|
||||
#include "ARMv7Function.h"
|
||||
#include "ARMv7Module.h"
|
||||
|
||||
LOG_CHANNEL(sceAppMgr);
|
||||
LOG_CHANNEL(sceAppUtil);
|
||||
LOG_CHANNEL(sceAudio);
|
||||
LOG_CHANNEL(sceAudiodec);
|
||||
LOG_CHANNEL(sceAudioenc);
|
||||
LOG_CHANNEL(sceAudioIn);
|
||||
LOG_CHANNEL(sceCamera);
|
||||
LOG_CHANNEL(sceCodecEngine);
|
||||
LOG_CHANNEL(sceCommonDialog);
|
||||
LOG_CHANNEL(sceCtrl);
|
||||
LOG_CHANNEL(sceDbg);
|
||||
LOG_CHANNEL(sceDeci4p);
|
||||
LOG_CHANNEL(sceDeflt);
|
||||
LOG_CHANNEL(sceDisplay);
|
||||
LOG_CHANNEL(sceFiber);
|
||||
LOG_CHANNEL(sceFios);
|
||||
LOG_CHANNEL(sceFpu);
|
||||
LOG_CHANNEL(sceGxm);
|
||||
LOG_CHANNEL(sceHttp);
|
||||
LOG_CHANNEL(sceIme);
|
||||
LOG_CHANNEL(sceJpeg);
|
||||
LOG_CHANNEL(sceJpegEnc);
|
||||
LOG_CHANNEL(sceLibc);
|
||||
LOG_CHANNEL(sceLibKernel);
|
||||
LOG_CHANNEL(sceLibm);
|
||||
LOG_CHANNEL(sceLibstdcxx);
|
||||
LOG_CHANNEL(sceLibXml);
|
||||
LOG_CHANNEL(sceLiveArea);
|
||||
LOG_CHANNEL(sceLocation);
|
||||
LOG_CHANNEL(sceMd5);
|
||||
LOG_CHANNEL(sceMotion);
|
||||
LOG_CHANNEL(sceMt19937);
|
||||
LOG_CHANNEL(sceNet);
|
||||
LOG_CHANNEL(sceNetCtl);
|
||||
LOG_CHANNEL(sceNgs);
|
||||
LOG_CHANNEL(sceNpBasic);
|
||||
LOG_CHANNEL(sceNpCommon);
|
||||
LOG_CHANNEL(sceNpManager);
|
||||
LOG_CHANNEL(sceNpMatching);
|
||||
LOG_CHANNEL(sceNpScore);
|
||||
LOG_CHANNEL(sceNpUtility);
|
||||
LOG_CHANNEL(scePerf);
|
||||
LOG_CHANNEL(scePgf);
|
||||
LOG_CHANNEL(scePhotoExport);
|
||||
LOG_CHANNEL(sceRazorCapture);
|
||||
LOG_CHANNEL(sceRtc);
|
||||
LOG_CHANNEL(sceSas);
|
||||
LOG_CHANNEL(sceScreenShot);
|
||||
LOG_CHANNEL(sceSfmt);
|
||||
LOG_CHANNEL(sceSha);
|
||||
LOG_CHANNEL(sceSqlite);
|
||||
LOG_CHANNEL(sceSsl);
|
||||
LOG_CHANNEL(sceSulpha);
|
||||
LOG_CHANNEL(sceSysmodule);
|
||||
LOG_CHANNEL(sceSystemGesture);
|
||||
LOG_CHANNEL(sceTouch);
|
||||
LOG_CHANNEL(sceUlt);
|
||||
LOG_CHANNEL(sceVideodec);
|
||||
LOG_CHANNEL(sceVoice);
|
||||
LOG_CHANNEL(sceVoiceQoS);
|
||||
|
||||
extern void armv7_init_tls();
|
||||
|
||||
extern std::string arm_get_function_name(const std::string& module, u32 fnid);
|
||||
@ -29,18 +91,18 @@ extern void arm_execute_function(ARMv7Thread& cpu, u32 index)
|
||||
{
|
||||
func(cpu);
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
LOG_ERROR(ARMv7, "Function '%s' aborted", cpu.last_function);
|
||||
cpu.last_function = previous_function;
|
||||
throw;
|
||||
}
|
||||
catch (EmulationStopped)
|
||||
{
|
||||
LOG_WARNING(ARMv7, "Function '%s' aborted", cpu.last_function);
|
||||
cpu.last_function = previous_function;
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOG_ERROR(ARMv7, "Function '%s' aborted", cpu.last_function);
|
||||
cpu.last_function = previous_function;
|
||||
throw;
|
||||
}
|
||||
|
||||
LOG_TRACE(ARMv7, "Function '%s' finished, r0=0x%x", cpu.last_function, cpu.GPR[0]);
|
||||
cpu.last_function = previous_function;
|
||||
@ -411,7 +473,7 @@ void arm_exec_loader::load() const
|
||||
|
||||
case 0x6c2224ba: // __sce_moduleinfo
|
||||
{
|
||||
ASSERT(addr == module_info.addr());
|
||||
VERIFY(addr == module_info.addr());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -546,8 +608,8 @@ void arm_exec_loader::load() const
|
||||
|
||||
LOG_NOTICE(LOADER, "__sce_process_param(*0x%x) analysis...", proc_param);
|
||||
|
||||
ASSERT(proc_param->size >= sizeof(psv_process_param_t));
|
||||
ASSERT(proc_param->ver == "PSP2"_u32);
|
||||
VERIFY(proc_param->size >= sizeof(psv_process_param_t));
|
||||
VERIFY(proc_param->ver == "PSP2"_u32);
|
||||
|
||||
LOG_NOTICE(LOADER, "*** size=0x%x; 0x%x, 0x%x, 0x%x", proc_param->size, proc_param->ver, proc_param->unk0, proc_param->unk1);
|
||||
|
||||
@ -563,7 +625,7 @@ void arm_exec_loader::load() const
|
||||
|
||||
LOG_NOTICE(LOADER, "__sce_libcparam(*0x%x) analysis...", libc_param);
|
||||
|
||||
ASSERT(libc_param->size >= 0x1c);
|
||||
VERIFY(libc_param->size >= 0x1c);
|
||||
|
||||
LOG_NOTICE(LOADER, "*** size=0x%x; 0x%x, 0x%x, 0x%x", libc_param->size, libc_param->unk0, libc_param->unk1, libc_param->unk2);
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/Config.h"
|
||||
#include "ARMv7Function.h"
|
||||
#include "ARMv7Callback.h"
|
||||
#include "ErrorCodes.h"
|
||||
@ -167,37 +166,3 @@ public:
|
||||
#define REG_FNID(module, nid, func, ...) arm_module_manager::register_static_function<decltype(&func), &func>(#module, #func, BIND_FUNC(func), nid, {__VA_ARGS__})
|
||||
|
||||
#define REG_VNID(module, nid, var, ...) arm_module_manager::register_static_variable<decltype(var), &var>(#module, #var, nid, {__VA_ARGS__})
|
||||
|
||||
struct SceDateTime
|
||||
{
|
||||
le_t<u16> year;
|
||||
le_t<u16> month;
|
||||
le_t<u16> day;
|
||||
le_t<u16> hour;
|
||||
le_t<u16> minute;
|
||||
le_t<u16> second;
|
||||
le_t<u32> microsecond;
|
||||
};
|
||||
|
||||
struct SceFVector3
|
||||
{
|
||||
le_t<f32> x, y, z;
|
||||
};
|
||||
|
||||
struct SceFQuaternion
|
||||
{
|
||||
le_t<f32> x, y, z, w;
|
||||
};
|
||||
|
||||
union SceUMatrix4
|
||||
{
|
||||
struct
|
||||
{
|
||||
le_t<f32> f[4][4];
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
le_t<s32> i[4][4];
|
||||
};
|
||||
};
|
@ -129,7 +129,7 @@ public:
|
||||
std::array<perf_counter, 6> counters{};
|
||||
|
||||
u32 PC = 0;
|
||||
s32 prio = 0;
|
||||
u32 prio = -1;
|
||||
u32 stack_addr = 0;
|
||||
u32 stack_size = 0;
|
||||
|
||||
@ -155,7 +155,7 @@ public:
|
||||
|
||||
void write_gpr(u32 n, u32 value, u32 size)
|
||||
{
|
||||
Expects(n < 16);
|
||||
EXPECTS(n < 16);
|
||||
|
||||
if (n < 15)
|
||||
{
|
||||
@ -169,7 +169,7 @@ public:
|
||||
|
||||
u32 read_gpr(u32 n)
|
||||
{
|
||||
Expects(n < 16);
|
||||
EXPECTS(n < 16);
|
||||
|
||||
if (n < 15)
|
||||
{
|
||||
@ -242,7 +242,7 @@ struct arm_gpr_cast_impl<vm::_ptr_base<T, AT>, void>
|
||||
|
||||
static inline vm::_ptr_base<T, AT> from(const u32 reg)
|
||||
{
|
||||
return{ arm_gpr_cast_impl<AT>::from(reg), vm::addr };
|
||||
return vm::cast(arm_gpr_cast_impl<AT>::from(reg));
|
||||
}
|
||||
};
|
||||
|
||||
@ -256,7 +256,7 @@ struct arm_gpr_cast_impl<vm::_ref_base<T, AT>, void>
|
||||
|
||||
static inline vm::_ref_base<T, AT> from(const u32 reg)
|
||||
{
|
||||
return{ arm_gpr_cast_impl<AT>::from(reg), vm::addr };
|
||||
return vm::cast(arm_gpr_cast_impl<AT>::from(reg));
|
||||
}
|
||||
};
|
||||
|
@ -179,9 +179,12 @@ struct arm_error_code
|
||||
{
|
||||
}
|
||||
|
||||
// Helper
|
||||
enum class not_an_error : s32 {};
|
||||
|
||||
// Silence any error
|
||||
constexpr arm_error_code(s32 value, const std::nothrow_t&)
|
||||
: value(value)
|
||||
constexpr arm_error_code(not_an_error value)
|
||||
: value(static_cast<s32>(value))
|
||||
{
|
||||
}
|
||||
|
||||
@ -193,7 +196,7 @@ struct arm_error_code
|
||||
};
|
||||
|
||||
// Helper macro for silencing possible error checks on returning arm_error_code values
|
||||
#define NOT_AN_ERROR(value) { static_cast<s32>(value), std::nothrow }
|
||||
#define NOT_AN_ERROR(...) static_cast<arm_error_code::not_an_error>(static_cast<s32>(__VA_ARGS__))
|
||||
|
||||
template<typename T, typename>
|
||||
struct arm_gpr_cast_impl;
|
38
rpcs3/Emu/PSP2/Modules/Common.h
Normal file
38
rpcs3/Emu/PSP2/Modules/Common.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/types.h"
|
||||
#include "Utilities/BEType.h"
|
||||
|
||||
struct SceDateTime
|
||||
{
|
||||
le_t<u16> year;
|
||||
le_t<u16> month;
|
||||
le_t<u16> day;
|
||||
le_t<u16> hour;
|
||||
le_t<u16> minute;
|
||||
le_t<u16> second;
|
||||
le_t<u32> microsecond;
|
||||
};
|
||||
|
||||
struct SceFVector3
|
||||
{
|
||||
le_t<f32> x, y, z;
|
||||
};
|
||||
|
||||
struct SceFQuaternion
|
||||
{
|
||||
le_t<f32> x, y, z, w;
|
||||
};
|
||||
|
||||
union SceUMatrix4
|
||||
{
|
||||
struct
|
||||
{
|
||||
le_t<f32> f[4][4];
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
le_t<s32> i[4][4];
|
||||
};
|
||||
};
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceAppMgr.h"
|
||||
|
||||
LOG_CHANNEL(sceAppMgr);
|
||||
logs::channel sceAppMgr("sceAppMgr", logs::level::notice);
|
||||
|
||||
s32 sceAppMgrReceiveEventNum(vm::ptr<s32> eventNum)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceAppUtil.h"
|
||||
|
||||
LOG_CHANNEL(sceAppUtil);
|
||||
logs::channel sceAppUtil("sceAppUtil", logs::level::notice);
|
||||
|
||||
s32 sceAppUtilInit(vm::cptr<SceAppUtilInitParam> initParam, vm::ptr<SceAppUtilBootParam> bootParam)
|
||||
{
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
struct SceAppUtilInitParam
|
||||
{
|
||||
le_t<u32> workBufSize;
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceAudio.h"
|
||||
|
||||
LOG_CHANNEL(sceAudio);
|
||||
logs::channel sceAudio("sceAudio", logs::level::notice);
|
||||
|
||||
s32 sceAudioOutOpenPort(s32 portType, s32 len, s32 freq, s32 param)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceAudioIn.h"
|
||||
|
||||
LOG_CHANNEL(sceAudioIn);
|
||||
logs::channel sceAudioIn("sceAudioIn", logs::level::notice);
|
||||
|
||||
s32 sceAudioInOpenPort(s32 portType, s32 grain, s32 freq, s32 param)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceAudiodec.h"
|
||||
|
||||
LOG_CHANNEL(sceAudiodec);
|
||||
logs::channel sceAudiodec("sceAudiodec", logs::level::notice);
|
||||
|
||||
s32 sceAudiodecInitLibrary(u32 codecType, vm::ptr<SceAudiodecInitParam> pInitParam)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceAudioenc.h"
|
||||
|
||||
LOG_CHANNEL(sceAudioenc);
|
||||
logs::channel sceAudioenc("sceAudioenc", logs::level::notice);
|
||||
|
||||
s32 sceAudioencInitLibrary(u32 codecType, vm::ptr<SceAudioencInitParam> pInitParam)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceCamera.h"
|
||||
|
||||
LOG_CHANNEL(sceCamera);
|
||||
logs::channel sceCamera("sceCamera", logs::level::notice);
|
||||
|
||||
s32 sceCameraOpen(s32 devnum, vm::ptr<SceCameraInfo> pInfo)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceCodecEngine.h"
|
||||
|
||||
LOG_CHANNEL(sceCodecEngine);
|
||||
logs::channel sceCodecEngine("sceCodecEngine", logs::level::notice);
|
||||
|
||||
s32 sceCodecEnginePmonStart()
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceCommonDialog.h"
|
||||
|
||||
LOG_CHANNEL(sceCommonDialog);
|
||||
logs::channel sceCommonDialog("sceCommonDialog", logs::level::notice);
|
||||
|
||||
s32 sceCommonDialogUpdate(vm::cptr<SceCommonDialogUpdateParam> updateParam)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceCtrl.h"
|
||||
|
||||
LOG_CHANNEL(sceCtrl);
|
||||
logs::channel sceCtrl("sceCtrl", logs::level::notice);
|
||||
|
||||
s32 sceCtrlSetSamplingMode(u32 uiMode)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceDbg.h"
|
||||
|
||||
LOG_CHANNEL(sceDbg);
|
||||
logs::channel sceDbg("sceDbg", logs::level::notice);
|
||||
|
||||
s32 sceDbgSetMinimumLogLevel(s32 minimumLogLevel)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceDeci4p.h"
|
||||
|
||||
LOG_CHANNEL(sceDeci4p);
|
||||
logs::channel sceDeci4p("sceDeci4p", logs::level::notice);
|
||||
|
||||
s32 sceKernelDeci4pOpen(vm::cptr<char> protoname, u32 protonum, u32 bufsize)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceDeflt.h"
|
||||
|
||||
LOG_CHANNEL(sceDeflt);
|
||||
logs::channel sceDeflt("sceDeflt", logs::level::notice);
|
||||
|
||||
s32 sceGzipIsValid(vm::cptr<void> pSrcGzip)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceDisplay.h"
|
||||
|
||||
LOG_CHANNEL(sceDisplay);
|
||||
logs::channel sceDisplay("sceDisplay", logs::level::notice);
|
||||
|
||||
s32 sceDisplayGetRefreshRate(vm::ptr<float> pFps)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceFiber.h"
|
||||
|
||||
LOG_CHANNEL(sceFiber);
|
||||
logs::channel sceFiber("sceFiber", logs::level::notice);
|
||||
|
||||
s32 _sceFiberInitializeImpl(vm::ptr<SceFiber> fiber, vm::cptr<char> name, vm::ptr<SceFiberEntry> entry, u32 argOnInitialize, vm::ptr<void> addrContext, u32 sizeContext, vm::cptr<SceFiberOptParam> optParam, u32 buildVersion)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceFios.h"
|
||||
|
||||
LOG_CHANNEL(sceFios);
|
||||
logs::channel sceFios("sceFios", logs::level::notice);
|
||||
|
||||
s32 sceFiosInitialize(vm::cptr<SceFiosParams> pParameters)
|
||||
{
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
using SceFiosOpCallback = s32(vm::ptr<void> pContext, s32 op, u8 event, s32 err);
|
||||
using SceFiosVprintfCallback = s32(vm::cptr<char> fmt, arm_va_args_t ap /* va_list */);
|
||||
using SceFiosMemcpyCallback = vm::ptr<void>(vm::ptr<void> dst, vm::cptr<void> src, u32 len);
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceFpu.h"
|
||||
|
||||
LOG_CHANNEL(sceFpu);
|
||||
logs::channel sceFpu("sceFpu", logs::level::notice);
|
||||
|
||||
float sceFpuSinf(float x)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceGxm.h"
|
||||
|
||||
LOG_CHANNEL(sceGxm);
|
||||
logs::channel sceGxm("sceGxm", logs::level::notice);
|
||||
|
||||
s32 sceGxmInitialize(vm::cptr<SceGxmInitializeParams> params)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceHttp.h"
|
||||
|
||||
LOG_CHANNEL(sceHttp);
|
||||
logs::channel sceHttp("sceHttp", logs::level::notice);
|
||||
|
||||
s32 sceHttpInit(u32 poolSize)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceIme.h"
|
||||
|
||||
LOG_CHANNEL(sceIme);
|
||||
logs::channel sceIme("sceIme", logs::level::notice);
|
||||
|
||||
s32 sceImeOpen(vm::ptr<SceImeParam> param)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceJpeg.h"
|
||||
|
||||
LOG_CHANNEL(sceJpeg);
|
||||
logs::channel sceJpeg("sceJpeg", logs::level::notice);
|
||||
|
||||
s32 sceJpegInitMJpeg(s32 maxSplitDecoder)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceJpegEnc.h"
|
||||
|
||||
LOG_CHANNEL(sceJpegEnc);
|
||||
logs::channel sceJpegEnc("sceJpegEnc", logs::level::notice);
|
||||
|
||||
s32 sceJpegEncoderGetContextSize()
|
||||
{
|
@ -1,18 +1,20 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/IPC.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceLibKernel.h"
|
||||
|
||||
#include "Utilities/StrUtil.h"
|
||||
#include "Utilities/lockless.h"
|
||||
|
||||
LOG_CHANNEL(sceLibKernel);
|
||||
#include <algorithm>
|
||||
|
||||
logs::channel sceLibKernel("sceLibKernel", logs::level::notice);
|
||||
|
||||
extern u64 get_system_time();
|
||||
|
||||
extern std::condition_variable& get_current_thread_cv();
|
||||
|
||||
s32 sceKernelAllocMemBlock(vm::cptr<char> name, s32 type, u32 vsize, vm::ptr<SceKernelAllocMemBlockOpt> pOpt)
|
||||
{
|
||||
throw EXCEPTION("");
|
||||
@ -75,7 +77,7 @@ arm_error_code sceKernelStartThread(s32 threadId, u32 argSize, vm::cptr<void> pA
|
||||
thread->GPR[1] = pos;
|
||||
|
||||
thread->state -= cpu_state::stop;
|
||||
thread->lock_notify();
|
||||
(*thread)->lock_notify();
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
@ -207,19 +209,6 @@ s32 sceKernelGetSystemInfo(vm::ptr<SceKernelSystemInfo> pInfo)
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
arm_error_code sceKernelGetThreadmgrUIDClass(s32 uid)
|
||||
{
|
||||
sceLibKernel.error("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid);
|
||||
|
||||
if (idm::check<ARMv7Thread>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_THREAD;
|
||||
if (idm::check<psv_semaphore_t>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_SEMA;
|
||||
if (idm::check<psv_event_flag_t>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_EVENT_FLAG;
|
||||
if (idm::check<psv_mutex_t>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_MUTEX;
|
||||
if (idm::check<psv_cond_t>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_COND;
|
||||
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
s32 sceKernelChangeThreadVfpException(s32 clearMask, s32 setMask)
|
||||
{
|
||||
sceLibKernel.todo("sceKernelChangeThreadVfpException(clearMask=0x%x, setMask=0x%x)", clearMask, setMask);
|
||||
@ -263,12 +252,7 @@ arm_error_code sceKernelWaitThreadEnd(s32 threadId, vm::ptr<s32> pExitStatus, vm
|
||||
{
|
||||
}
|
||||
|
||||
while (!(thread->state & cpu_state::exit))
|
||||
{
|
||||
CHECK_EMU_STATUS;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
}
|
||||
(*thread)->join();
|
||||
|
||||
if (pExitStatus)
|
||||
{
|
||||
@ -374,20 +358,352 @@ s32 sceKernelWaitMultipleEventsCB(vm::ptr<SceKernelWaitEvent> pWaitEventList, s3
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
// Event flag functions
|
||||
struct psp2_event_flag final
|
||||
{
|
||||
struct alignas(8) ctrl_t
|
||||
{
|
||||
u32 waiters;
|
||||
u32 pattern;
|
||||
};
|
||||
|
||||
atomic_t<ctrl_t> ctrl; // Sync variable
|
||||
atomic_t<u64> wait_ctr{}; // FIFO ordering helper
|
||||
|
||||
using ipc = ipc_manager<psp2_event_flag, std::string>;
|
||||
|
||||
const std::string name; // IPC/Debug Name
|
||||
atomic_t<u32> ipc_ref{1}; // IPC Ref Count
|
||||
|
||||
const u32 attr;
|
||||
const u32 init;
|
||||
|
||||
psp2_event_flag(std::string&& name, u32 attr, u32 pattern)
|
||||
: ctrl({0, pattern})
|
||||
, name(std::move(name))
|
||||
, attr(attr)
|
||||
, init(pattern)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool pat_test(u32 current, u32 pattern, u32 mode)
|
||||
{
|
||||
const u32 or_mask = mode & SCE_KERNEL_EVF_WAITMODE_OR ? pattern : 0;
|
||||
const u32 and_mask = mode & SCE_KERNEL_EVF_WAITMODE_OR ? 0 : pattern;
|
||||
|
||||
return (current & or_mask) != 0 && (current & and_mask) == and_mask;
|
||||
}
|
||||
|
||||
// Get mask for bitwise AND for bit clear operation
|
||||
static inline u32 pat_clear(u32 pattern, u32 mode)
|
||||
{
|
||||
return
|
||||
mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_ALL ? 0 :
|
||||
mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_PAT ? ~pattern : ~0;
|
||||
}
|
||||
|
||||
// Commands
|
||||
enum class task : u32
|
||||
{
|
||||
null = 0,
|
||||
wait,
|
||||
poll,
|
||||
set,
|
||||
clear,
|
||||
cancel,
|
||||
destroy,
|
||||
signal,
|
||||
};
|
||||
|
||||
struct alignas(8) cmd_t
|
||||
{
|
||||
task type;
|
||||
u32 arg;
|
||||
};
|
||||
|
||||
// Enqueue a command and try to execute all pending commands. Commands are executed sequentially.
|
||||
// Returns true if the command has been completed immediately. Its status is unknown otherwise.
|
||||
bool exec(task type, u32 arg)
|
||||
{
|
||||
// Acquire position in the queue
|
||||
const u32 push_pos = m_workload.push_begin();
|
||||
|
||||
// Make the command
|
||||
cmd_t cmd{type, arg};
|
||||
|
||||
u32 pos = m_workload.peek();
|
||||
|
||||
// Check optimistic case
|
||||
if (UNLIKELY(pos != push_pos))
|
||||
{
|
||||
// Write the command
|
||||
m_workload[push_pos] = cmd;
|
||||
pos = m_workload.peek(); // ???
|
||||
|
||||
// Try to acquire a command
|
||||
cmd = m_workload[pos].exchange({task::null});
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
switch (cmd.type)
|
||||
{
|
||||
case task::null:
|
||||
{
|
||||
// Return immediately if can't process a command. Possible reasons:
|
||||
// 1) The command has not yet been written
|
||||
// 2) The command has already been acquired
|
||||
return push_pos < pos;
|
||||
}
|
||||
|
||||
case task::wait: op_wait(cmd.arg); break;
|
||||
case task::poll: op_poll(cmd.arg); break;
|
||||
case task::set: op_set(cmd.arg); break;
|
||||
case task::clear: op_clear(cmd.arg); break;
|
||||
case task::cancel: op_stop(vm::cast(cmd.arg), SCE_KERNEL_ERROR_WAIT_CANCEL); break;
|
||||
case task::destroy: op_stop(vm::cast(cmd.arg), SCE_KERNEL_ERROR_WAIT_DELETE); break;
|
||||
|
||||
case task::signal:
|
||||
{
|
||||
idm::get<ARMv7Thread>(cmd.arg, [&](u32, ARMv7Thread& cpu)
|
||||
{
|
||||
cpu.state += cpu_state::signal;
|
||||
cpu->lock_notify();
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: ASSUME(0);
|
||||
}
|
||||
|
||||
// Get next position
|
||||
pos = m_workload.pop_end();
|
||||
|
||||
// Exit after the cleanup
|
||||
if (LIKELY(!pos)) return true;
|
||||
|
||||
// Get next command
|
||||
cmd = m_workload[pos].exchange({task::null});
|
||||
}
|
||||
}
|
||||
|
||||
// Enqueue a command and ensure its completion.
|
||||
void sync(ARMv7Thread& cpu, task type, u32 arg)
|
||||
{
|
||||
if (UNLIKELY(!exec(type, arg)))
|
||||
{
|
||||
if (!exec(task::signal, cpu.id))
|
||||
{
|
||||
thread_lock{cpu}, thread_ctrl::wait(WRAP_EXPR(cpu.state.test_and_reset(cpu_state::signal)));
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu.state -= cpu_state::signal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
lf_fifo<atomic_t<cmd_t>, 16> m_workload;
|
||||
|
||||
// Check condition
|
||||
void op_wait(u32 thread_id)
|
||||
{
|
||||
idm::get<ARMv7Thread>(thread_id, [&](u32, ARMv7Thread& cpu)
|
||||
{
|
||||
const u32 pattern = ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state) -> u32
|
||||
{
|
||||
const u32 pat = state.pattern;
|
||||
if (pat_test(pat, cpu.GPR[1], cpu.GPR[0]))
|
||||
{
|
||||
state.pattern &= pat_clear(cpu.GPR[1], cpu.GPR[0]);
|
||||
state.waiters -= attr & SCE_KERNEL_ATTR_MULTI ? 1 : cpu.id;
|
||||
return pat;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
if (pattern)
|
||||
{
|
||||
cpu.GPR[0] = SCE_OK;
|
||||
cpu.GPR[1] = pattern;
|
||||
cpu.state += cpu_state::signal;
|
||||
cpu->lock_notify();
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu.owner = this;
|
||||
cpu.GPR_D[1] = ++wait_ctr;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check condition
|
||||
void op_poll(u32 thread_id)
|
||||
{
|
||||
idm::get<ARMv7Thread>(thread_id, [&](u32, ARMv7Thread& cpu)
|
||||
{
|
||||
cpu.GPR[1] = ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state) -> u32
|
||||
{
|
||||
const u32 pat = state.pattern;
|
||||
if (pat_test(pat, cpu.GPR[1], cpu.GPR[0]))
|
||||
{
|
||||
state.pattern &= pat_clear(cpu.GPR[1], cpu.GPR[0]);
|
||||
return pat;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Set pattern bits and wake up threads
|
||||
void op_set(u32 pattern)
|
||||
{
|
||||
const auto new_state = ctrl.op_fetch([&](psp2_event_flag::ctrl_t& state)
|
||||
{
|
||||
state.pattern |= pattern;
|
||||
});
|
||||
|
||||
if (new_state.waiters)
|
||||
{
|
||||
std::vector<std::reference_wrapper<ARMv7Thread>> threads;
|
||||
|
||||
// Check and lock appropriate threads
|
||||
if (attr & SCE_KERNEL_ATTR_MULTI)
|
||||
{
|
||||
threads.reserve(new_state.waiters);
|
||||
|
||||
idm::select<ARMv7Thread>([&](u32 id, ARMv7Thread& cpu)
|
||||
{
|
||||
if (cpu->lock_if(WRAP_EXPR(cpu.owner == this && pat_test(new_state.pattern, cpu.GPR[1], cpu.GPR[0]))))
|
||||
{
|
||||
threads.emplace_back(cpu);
|
||||
}
|
||||
});
|
||||
|
||||
// Sort the thread list using appropriate scheduling policy
|
||||
std::sort(threads.begin(), threads.end(), [&](const ARMv7Thread& cpu1, const ARMv7Thread& cpu2)
|
||||
{
|
||||
if (attr & SCE_KERNEL_ATTR_TH_PRIO && cpu1.prio != cpu2.prio)
|
||||
{
|
||||
return cpu1.prio < cpu2.prio;
|
||||
}
|
||||
else
|
||||
{
|
||||
return cpu1.GPR_D[1] < cpu2.GPR_D[1];
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
idm::get<ARMv7Thread>(new_state.waiters, [&](u32 id, ARMv7Thread& cpu)
|
||||
{
|
||||
if (cpu->lock_if(WRAP_EXPR(cpu.owner == this && pat_test(new_state.pattern, cpu.GPR[1], cpu.GPR[0]))))
|
||||
{
|
||||
threads.emplace_back(cpu);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Wake up threads
|
||||
for (ARMv7Thread& cpu : threads)
|
||||
{
|
||||
const u32 old_pattern = ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state) -> u32
|
||||
{
|
||||
const u32 pat = state.pattern;
|
||||
|
||||
if (pat_test(pat, cpu.GPR[1], cpu.GPR[0]))
|
||||
{
|
||||
state.pattern &= pat_clear(cpu.GPR[1], cpu.GPR[0]);
|
||||
state.waiters -= attr & SCE_KERNEL_ATTR_MULTI ? 1 : cpu.id;
|
||||
return pat;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
if (old_pattern)
|
||||
{
|
||||
cpu.GPR[0] = SCE_OK;
|
||||
cpu.GPR[1] = old_pattern;
|
||||
cpu.state += cpu_state::signal;
|
||||
cpu.owner = nullptr;
|
||||
cpu->unlock();
|
||||
cpu->notify();
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu->unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear pattern bits (bitwise AND)
|
||||
void op_clear(u32 pattern)
|
||||
{
|
||||
ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state)
|
||||
{
|
||||
state.pattern &= pattern;
|
||||
});
|
||||
}
|
||||
|
||||
// Wake up all threads
|
||||
void op_stop(vm::ptr<u32> ptr, s32 error)
|
||||
{
|
||||
s32 result = 0;
|
||||
const u32 pattern = ptr ? ptr->value() : ctrl.load().pattern;
|
||||
|
||||
idm::select<ARMv7Thread>([&](u32, ARMv7Thread& cpu)
|
||||
{
|
||||
if (cpu->lock_if(WRAP_EXPR(cpu.owner == this)))
|
||||
{
|
||||
cpu.GPR[0] = error;
|
||||
cpu.GPR[1] = pattern;
|
||||
cpu.state += cpu_state::signal;
|
||||
cpu.owner = nullptr;
|
||||
cpu->unlock();
|
||||
cpu->notify();
|
||||
result++;
|
||||
}
|
||||
});
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
*ptr = result;
|
||||
}
|
||||
|
||||
ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state)
|
||||
{
|
||||
state.pattern = pattern;
|
||||
state.waiters = attr & SCE_KERNEL_ATTR_MULTI ? state.waiters - result : 0;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template<> DECLARE(psp2_event_flag::ipc::g_ipc) {};
|
||||
|
||||
arm_error_code sceKernelCreateEventFlag(vm::cptr<char> pName, u32 attr, u32 initPattern, vm::cptr<SceKernelEventFlagOptParam> pOptParam)
|
||||
{
|
||||
sceLibKernel.error("sceKernelCreateEventFlag(pName=*0x%x, attr=0x%x, initPattern=0x%x, pOptParam=*0x%x)", pName, attr, initPattern, pOptParam);
|
||||
|
||||
return NOT_AN_ERROR(idm::make<psv_event_flag_t>(pName.get_ptr(), attr, initPattern));
|
||||
// Create EVF
|
||||
auto evf = std::make_shared<psp2_event_flag>(pName.get_ptr(), attr, initPattern);
|
||||
|
||||
// Try to register IPC name, only if not empty string (TODO)
|
||||
if (evf->name.empty() || !psp2_event_flag::ipc::add(evf->name, WRAP_EXPR(evf))) evf->ipc_ref = 0;
|
||||
|
||||
// Register ID
|
||||
return NOT_AN_ERROR(idm::import_existing(evf));
|
||||
}
|
||||
|
||||
arm_error_code sceKernelDeleteEventFlag(s32 evfId)
|
||||
{
|
||||
sceLibKernel.error("sceKernelDeleteEventFlag(evfId=0x%x)", evfId);
|
||||
|
||||
const auto evf = idm::withdraw<psv_event_flag_t>(evfId);
|
||||
const auto evf = idm::withdraw<psp2_event_flag>(evfId);
|
||||
|
||||
if (!evf)
|
||||
{
|
||||
@ -395,9 +711,15 @@ arm_error_code sceKernelDeleteEventFlag(s32 evfId)
|
||||
}
|
||||
|
||||
// Unregister IPC name
|
||||
if (evf->ref.atomic_op(ipc_ref_try_unregister))
|
||||
if (evf->ipc_ref.fetch_op([](u32& ref) { if (ref) ref--; }))
|
||||
{
|
||||
evf->destroy();
|
||||
psp2_event_flag::ipc::remove(evf->name);
|
||||
}
|
||||
|
||||
// Finalize the last reference
|
||||
if (!evf->ipc_ref)
|
||||
{
|
||||
evf->exec(psp2_event_flag::task::destroy, 0);
|
||||
}
|
||||
|
||||
return SCE_OK;
|
||||
@ -407,35 +729,32 @@ arm_error_code sceKernelOpenEventFlag(vm::cptr<char> pName)
|
||||
{
|
||||
sceLibKernel.error("sceKernelOpenEventFlag(pName=*0x%x)", pName);
|
||||
|
||||
// For now, go through all objects to find the name
|
||||
for (const auto& data : idm::get_map<psv_event_flag_t>())
|
||||
{
|
||||
const auto& evf = data.second;
|
||||
const auto evf = psp2_event_flag::ipc::get(pName.get_ptr());
|
||||
|
||||
if (evf->name == pName.get_ptr() && evf->ref.atomic_op(ipc_ref_try_inc))
|
||||
{
|
||||
return NOT_AN_ERROR(idm::import_existing(evf));
|
||||
}
|
||||
// Try to add IPC reference
|
||||
if (!evf || !evf->ipc_ref.fetch_op([](u32& ref) { if (ref) ref++; }))
|
||||
{
|
||||
return SCE_KERNEL_ERROR_UID_CANNOT_FIND_BY_NAME;
|
||||
}
|
||||
|
||||
return SCE_KERNEL_ERROR_UID_CANNOT_FIND_BY_NAME;
|
||||
return NOT_AN_ERROR(idm::import_existing(evf));
|
||||
}
|
||||
|
||||
arm_error_code sceKernelCloseEventFlag(s32 evfId)
|
||||
{
|
||||
sceLibKernel.error("sceKernelCloseEventFlag(evfId=0x%x)", evfId);
|
||||
|
||||
const auto evf = idm::withdraw<psv_event_flag_t>(evfId);
|
||||
const auto evf = idm::withdraw<psp2_event_flag>(evfId);
|
||||
|
||||
if (!evf)
|
||||
if (!evf || !evf->ipc_ref)
|
||||
{
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
// Decrement IPC ref
|
||||
if (evf->ref.atomic_op(ipc_ref_try_dec))
|
||||
// Remove one IPC reference
|
||||
if (!evf->ipc_ref.op_fetch([](u32& ref) { if (ref) ref--; }))
|
||||
{
|
||||
evf->destroy();
|
||||
evf->exec(psp2_event_flag::task::destroy, 0);
|
||||
}
|
||||
|
||||
return SCE_OK;
|
||||
@ -448,52 +767,64 @@ arm_error_code sceKernelWaitEventFlag(ARMv7Thread& cpu, s32 evfId, u32 bitPatter
|
||||
const u64 start_time = pTimeout ? get_system_time() : 0;
|
||||
const u32 timeout = pTimeout ? pTimeout->value() : 0;
|
||||
|
||||
const auto evf = idm::get<psv_event_flag_t>(evfId);
|
||||
const auto evf = idm::get<psp2_event_flag>(evfId);
|
||||
|
||||
if (!evf)
|
||||
{
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock(evf->mutex);
|
||||
|
||||
const u32 result = evf->pattern.fetch_op(event_flag_try_poll, bitPattern, waitMode);
|
||||
|
||||
if (event_flag_test(result, bitPattern, waitMode))
|
||||
// First chance
|
||||
const auto state = evf->ctrl.fetch_op([&](psp2_event_flag::ctrl_t& state)
|
||||
{
|
||||
if (pResultPat) *pResultPat = result;
|
||||
if (!state.waiters && psp2_event_flag::pat_test(state.pattern, bitPattern, waitMode))
|
||||
{
|
||||
state.pattern &= psp2_event_flag::pat_clear(bitPattern, waitMode);
|
||||
}
|
||||
else if (evf->attr & SCE_KERNEL_ATTR_MULTI)
|
||||
{
|
||||
state.waiters++;
|
||||
}
|
||||
else if (!state.waiters)
|
||||
{
|
||||
state.waiters = cpu.id;
|
||||
}
|
||||
});
|
||||
|
||||
if (state.waiters && !(evf->attr & SCE_KERNEL_ATTR_MULTI))
|
||||
{
|
||||
return SCE_KERNEL_ERROR_EVF_MULTI;
|
||||
}
|
||||
|
||||
if (!state.waiters && psp2_event_flag::pat_test(state.pattern, bitPattern, waitMode))
|
||||
{
|
||||
if (pResultPat) *pResultPat = state.pattern;
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
// fixup register values for external use
|
||||
// Set register values for external use
|
||||
cpu.GPR[0] = waitMode;
|
||||
cpu.GPR[1] = bitPattern;
|
||||
cpu.GPR[2] = waitMode;
|
||||
|
||||
// add waiter; attributes are ignored in current implementation
|
||||
sleep_entry<cpu_thread> waiter(evf->sq, cpu);
|
||||
|
||||
while (!cpu.state.test_and_reset(cpu_state::signal))
|
||||
// Second chance
|
||||
if (evf->exec(psp2_event_flag::task::wait, cpu.id) && cpu.state.test_and_reset(cpu_state::signal))
|
||||
{
|
||||
CHECK_EMU_STATUS;
|
||||
if (pResultPat) *pResultPat = cpu.GPR[1];
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
if (pTimeout)
|
||||
cpu_thread_lock entry(cpu);
|
||||
|
||||
if (!thread_ctrl::wait(timeout, WRAP_EXPR(cpu.state.test_and_reset(cpu_state::signal))))
|
||||
{
|
||||
// Timeout cleanup
|
||||
cpu.owner = nullptr;
|
||||
cpu.GPR[0] = SCE_KERNEL_ERROR_WAIT_TIMEOUT;
|
||||
cpu.GPR[1] = evf->ctrl.atomic_op([&](psp2_event_flag::ctrl_t& state)
|
||||
{
|
||||
const u64 passed = get_system_time() - start_time;
|
||||
|
||||
if (passed >= timeout)
|
||||
{
|
||||
cpu.GPR[0] = SCE_KERNEL_ERROR_WAIT_TIMEOUT;
|
||||
cpu.GPR[1] = evf->pattern;
|
||||
break;
|
||||
}
|
||||
|
||||
get_current_thread_cv().wait_for(lock, std::chrono::microseconds(timeout - passed));
|
||||
}
|
||||
else
|
||||
{
|
||||
get_current_thread_cv().wait(lock);
|
||||
}
|
||||
state.waiters -= evf->attr & SCE_KERNEL_ATTR_MULTI ? 1 : cpu.id;
|
||||
return state.pattern;
|
||||
});
|
||||
}
|
||||
|
||||
if (pResultPat) *pResultPat = cpu.GPR[1];
|
||||
@ -509,73 +840,63 @@ arm_error_code sceKernelWaitEventFlagCB(ARMv7Thread& cpu, s32 evfId, u32 bitPatt
|
||||
return sceKernelWaitEventFlag(cpu, evfId, bitPattern, waitMode, pResultPat, pTimeout);
|
||||
}
|
||||
|
||||
arm_error_code sceKernelPollEventFlag(s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr<u32> pResultPat)
|
||||
arm_error_code sceKernelPollEventFlag(ARMv7Thread& cpu, s32 evfId, u32 bitPattern, u32 waitMode, vm::ptr<u32> pResultPat)
|
||||
{
|
||||
sceLibKernel.error("sceKernelPollEventFlag(evfId=0x%x, bitPattern=0x%x, waitMode=0x%x, pResultPat=*0x%x)", evfId, bitPattern, waitMode, pResultPat);
|
||||
|
||||
const auto evf = idm::get<psv_event_flag_t>(evfId);
|
||||
const auto evf = idm::get<psp2_event_flag>(evfId);
|
||||
|
||||
if (!evf)
|
||||
{
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(evf->mutex);
|
||||
|
||||
const u32 result = evf->pattern.fetch_op(event_flag_try_poll, bitPattern, waitMode);
|
||||
|
||||
if (!event_flag_test(result, bitPattern, waitMode))
|
||||
// First chance
|
||||
const auto state = evf->ctrl.fetch_op([&](psp2_event_flag::ctrl_t& state)
|
||||
{
|
||||
return SCE_KERNEL_ERROR_EVENT_COND;
|
||||
if (!state.waiters && psp2_event_flag::pat_test(state.pattern, bitPattern, waitMode))
|
||||
{
|
||||
state.pattern &= psp2_event_flag::pat_clear(bitPattern, waitMode);
|
||||
}
|
||||
});
|
||||
|
||||
if (psp2_event_flag::pat_test(state.pattern, bitPattern, waitMode))
|
||||
{
|
||||
if (!state.waiters)
|
||||
{
|
||||
*pResultPat = state.pattern;
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
cpu.GPR[0] = waitMode;
|
||||
cpu.GPR[1] = bitPattern;
|
||||
|
||||
evf->sync(cpu, psp2_event_flag::task::poll, cpu.id);
|
||||
|
||||
if (cpu.GPR[1])
|
||||
{
|
||||
*pResultPat = cpu.GPR[1];
|
||||
return SCE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*pResultPat = result;
|
||||
|
||||
return SCE_OK;
|
||||
return NOT_AN_ERROR(SCE_KERNEL_ERROR_EVENT_COND);
|
||||
}
|
||||
|
||||
arm_error_code sceKernelSetEventFlag(s32 evfId, u32 bitPattern)
|
||||
{
|
||||
sceLibKernel.error("sceKernelSetEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern);
|
||||
|
||||
const auto evf = idm::get<psv_event_flag_t>(evfId);
|
||||
const auto evf = idm::get<psp2_event_flag>(evfId);
|
||||
|
||||
if (!evf)
|
||||
{
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(evf->mutex);
|
||||
|
||||
evf->pattern |= bitPattern;
|
||||
|
||||
auto pred = [&](cpu_thread* thread) -> bool
|
||||
if (!evf->exec(psp2_event_flag::task::set, bitPattern))
|
||||
{
|
||||
auto& cpu = static_cast<ARMv7Thread&>(*thread);
|
||||
|
||||
// load pattern and mode from registers
|
||||
const u32 pattern = cpu.GPR[1];
|
||||
const u32 mode = cpu.GPR[2];
|
||||
|
||||
// check specific pattern
|
||||
const u32 result = evf->pattern.fetch_op(event_flag_try_poll, pattern, mode);
|
||||
|
||||
if (event_flag_test(result, pattern, mode))
|
||||
{
|
||||
// save pattern
|
||||
cpu.GPR[0] = SCE_OK;
|
||||
cpu.GPR[1] = result;
|
||||
|
||||
thread->state += cpu_state::signal;
|
||||
thread->notify();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// check all waiters; protocol is ignored in current implementation
|
||||
evf->sq.erase(std::remove_if(evf->sq.begin(), evf->sq.end(), pred), evf->sq.end());
|
||||
}
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
@ -584,45 +905,34 @@ arm_error_code sceKernelClearEventFlag(s32 evfId, u32 bitPattern)
|
||||
{
|
||||
sceLibKernel.error("sceKernelClearEventFlag(evfId=0x%x, bitPattern=0x%x)", evfId, bitPattern);
|
||||
|
||||
const auto evf = idm::get<psv_event_flag_t>(evfId);
|
||||
const auto evf = idm::get<psp2_event_flag>(evfId);
|
||||
|
||||
if (!evf)
|
||||
{
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(evf->mutex);
|
||||
|
||||
evf->pattern &= ~bitPattern;
|
||||
if (!evf->exec(psp2_event_flag::task::clear, bitPattern))
|
||||
{
|
||||
}
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
arm_error_code sceKernelCancelEventFlag(s32 evfId, u32 setPattern, vm::ptr<s32> pNumWaitThreads)
|
||||
arm_error_code sceKernelCancelEventFlag(ARMv7Thread& cpu, s32 evfId, u32 setPattern, vm::ptr<s32> pNumWaitThreads)
|
||||
{
|
||||
sceLibKernel.error("sceKernelCancelEventFlag(evfId=0x%x, setPattern=0x%x, pNumWaitThreads=*0x%x)", evfId, setPattern, pNumWaitThreads);
|
||||
|
||||
const auto evf = idm::get<psv_event_flag_t>(evfId);
|
||||
const auto evf = idm::get<psp2_event_flag>(evfId);
|
||||
|
||||
if (!evf)
|
||||
{
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(evf->mutex);
|
||||
*pNumWaitThreads = setPattern;
|
||||
|
||||
for (auto& thread : evf->sq)
|
||||
{
|
||||
static_cast<ARMv7Thread&>(*thread).GPR[0] = SCE_KERNEL_ERROR_WAIT_CANCEL;
|
||||
static_cast<ARMv7Thread&>(*thread).GPR[1] = setPattern;
|
||||
thread->state += cpu_state::signal;
|
||||
thread->notify();
|
||||
}
|
||||
|
||||
*pNumWaitThreads = static_cast<u32>(evf->sq.size());
|
||||
|
||||
evf->pattern = setPattern;
|
||||
evf->sq.clear();
|
||||
evf->sync(cpu, psp2_event_flag::task::cancel, pNumWaitThreads.addr());
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
@ -631,15 +941,13 @@ arm_error_code sceKernelGetEventFlagInfo(s32 evfId, vm::ptr<SceKernelEventFlagIn
|
||||
{
|
||||
sceLibKernel.error("sceKernelGetEventFlagInfo(evfId=0x%x, pInfo=*0x%x)", evfId, pInfo);
|
||||
|
||||
const auto evf = idm::get<psv_event_flag_t>(evfId);
|
||||
const auto evf = idm::get<psp2_event_flag>(evfId);
|
||||
|
||||
if (!evf)
|
||||
{
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(evf->mutex);
|
||||
|
||||
pInfo->size = SIZE_32(SceKernelEventFlagInfo);
|
||||
pInfo->evfId = evfId;
|
||||
|
||||
@ -647,8 +955,11 @@ arm_error_code sceKernelGetEventFlagInfo(s32 evfId, vm::ptr<SceKernelEventFlagIn
|
||||
|
||||
pInfo->attr = evf->attr;
|
||||
pInfo->initPattern = evf->init;
|
||||
pInfo->currentPattern = evf->pattern;
|
||||
pInfo->numWaitThreads = static_cast<u32>(evf->sq.size());
|
||||
|
||||
const auto state = evf->ctrl.load();
|
||||
|
||||
pInfo->currentPattern = state.pattern;
|
||||
pInfo->numWaitThreads = evf->attr & SCE_KERNEL_ATTR_MULTI ? state.waiters : state.waiters != 0;
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
@ -659,14 +970,14 @@ arm_error_code sceKernelCreateSema(vm::cptr<char> pName, u32 attr, s32 initCount
|
||||
{
|
||||
sceLibKernel.error("sceKernelCreateSema(pName=*0x%x, attr=0x%x, initCount=%d, maxCount=%d, pOptParam=*0x%x)", pName, attr, initCount, maxCount, pOptParam);
|
||||
|
||||
return NOT_AN_ERROR(idm::make<psv_semaphore_t>(pName.get_ptr(), attr, initCount, maxCount));
|
||||
return NOT_AN_ERROR(idm::make<psp2_semaphore>(pName.get_ptr(), attr, initCount, maxCount));
|
||||
}
|
||||
|
||||
arm_error_code sceKernelDeleteSema(s32 semaId)
|
||||
{
|
||||
sceLibKernel.error("sceKernelDeleteSema(semaId=0x%x)", semaId);
|
||||
|
||||
const auto sema = idm::withdraw<psv_semaphore_t>(semaId);
|
||||
const auto sema = idm::withdraw<psp2_semaphore>(semaId);
|
||||
|
||||
if (!sema)
|
||||
{
|
||||
@ -692,7 +1003,7 @@ arm_error_code sceKernelWaitSema(s32 semaId, s32 needCount, vm::ptr<u32> pTimeou
|
||||
{
|
||||
sceLibKernel.error("sceKernelWaitSema(semaId=0x%x, needCount=%d, pTimeout=*0x%x)", semaId, needCount, pTimeout);
|
||||
|
||||
const auto sema = idm::get<psv_semaphore_t>(semaId);
|
||||
const auto sema = idm::get<psp2_semaphore>(semaId);
|
||||
|
||||
if (!sema)
|
||||
{
|
||||
@ -735,14 +1046,14 @@ arm_error_code sceKernelCreateMutex(vm::cptr<char> pName, u32 attr, s32 initCoun
|
||||
{
|
||||
sceLibKernel.error("sceKernelCreateMutex(pName=*0x%x, attr=0x%x, initCount=%d, pOptParam=*0x%x)", pName, attr, initCount, pOptParam);
|
||||
|
||||
return NOT_AN_ERROR(idm::make<psv_mutex_t>(pName.get_ptr(), attr, initCount));
|
||||
return NOT_AN_ERROR(idm::make<psp2_mutex>(pName.get_ptr(), attr, initCount));
|
||||
}
|
||||
|
||||
arm_error_code sceKernelDeleteMutex(s32 mutexId)
|
||||
{
|
||||
sceLibKernel.error("sceKernelDeleteMutex(mutexId=0x%x)", mutexId);
|
||||
|
||||
const auto mutex = idm::withdraw<psv_mutex_t>(mutexId);
|
||||
const auto mutex = idm::withdraw<psp2_mutex>(mutexId);
|
||||
|
||||
if (!mutex)
|
||||
{
|
||||
@ -842,21 +1153,21 @@ arm_error_code sceKernelCreateCond(vm::cptr<char> pName, u32 attr, s32 mutexId,
|
||||
{
|
||||
sceLibKernel.error("sceKernelCreateCond(pName=*0x%x, attr=0x%x, mutexId=0x%x, pOptParam=*0x%x)", pName, attr, mutexId, pOptParam);
|
||||
|
||||
const auto mutex = idm::get<psv_mutex_t>(mutexId);
|
||||
const auto mutex = idm::get<psp2_mutex>(mutexId);
|
||||
|
||||
if (!mutex)
|
||||
{
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
return NOT_AN_ERROR(idm::make<psv_cond_t>(pName.get_ptr(), attr, mutex));
|
||||
return NOT_AN_ERROR(idm::make<psp2_cond>(pName.get_ptr(), attr, mutex));
|
||||
}
|
||||
|
||||
arm_error_code sceKernelDeleteCond(s32 condId)
|
||||
{
|
||||
sceLibKernel.error("sceKernelDeleteCond(condId=0x%x)", condId);
|
||||
|
||||
const auto cond = idm::withdraw<psv_cond_t>(condId);
|
||||
const auto cond = idm::withdraw<psp2_cond>(condId);
|
||||
|
||||
if (!cond)
|
||||
{
|
||||
@ -1121,6 +1432,19 @@ s32 sceKernelGetRWLockInfo(s32 rwLockId, vm::ptr<SceKernelRWLockInfo> pInfo)
|
||||
throw EXCEPTION("");
|
||||
}
|
||||
|
||||
arm_error_code sceKernelGetThreadmgrUIDClass(s32 uid)
|
||||
{
|
||||
sceLibKernel.error("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid);
|
||||
|
||||
if (idm::check<ARMv7Thread>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_THREAD;
|
||||
if (idm::check<psp2_semaphore>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_SEMA;
|
||||
if (idm::check<psp2_event_flag>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_EVENT_FLAG;
|
||||
if (idm::check<psp2_mutex>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_MUTEX;
|
||||
if (idm::check<psp2_cond>(uid)) return SCE_KERNEL_THREADMGR_UID_CLASS_COND;
|
||||
|
||||
return SCE_KERNEL_ERROR_INVALID_UID;
|
||||
}
|
||||
|
||||
// IO/File functions
|
||||
|
||||
s32 sceIoRemove(vm::cptr<char> filename)
|
@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/SleepQueue.h"
|
||||
#include "Emu/ARMv7/ErrorCodes.h"
|
||||
#include "Emu/PSP2/ErrorCodes.h"
|
||||
#include "Emu/PSP2/Modules/Common.h"
|
||||
|
||||
// Error Codes
|
||||
|
||||
enum SceLibKernelError : s32
|
||||
{
|
||||
SCE_KERNEL_ERROR_ERROR = ERROR_CODE(0x80020001),
|
||||
@ -99,6 +98,7 @@ enum SceLibKernelError : s32
|
||||
SCE_KERNEL_ERROR_ILLEGAL_SELF_HEADER = ERROR_CODE(0x80025002),
|
||||
};
|
||||
|
||||
// Error Codes
|
||||
enum SceLibKernelError0 : s32
|
||||
{
|
||||
SCE_KERNEL_ERROR_EXCPMGR_ERROR = ERROR_CODE(0x80027000),
|
||||
@ -204,6 +204,7 @@ enum SceLibKernelError0 : s32
|
||||
SCE_KERNEL_ERROR_RW_LOCK_FAILED_TO_UNLOCK = ERROR_CODE(0x80028046),
|
||||
};
|
||||
|
||||
// Error Codes
|
||||
enum SceLibKernelError1 : s32
|
||||
{
|
||||
SCE_KERNEL_ERROR_PROCESSMGR_ERROR = ERROR_CODE(0x80029000),
|
||||
@ -535,7 +536,8 @@ inline const char* arm_error_code::print(SceLibKernelError1 error)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
enum psv_object_class_t : u32
|
||||
// PSP2 UID Class
|
||||
enum : u32
|
||||
{
|
||||
SCE_KERNEL_UID_CLASS_PROCESS = 0,
|
||||
SCE_KERNEL_THREADMGR_UID_CLASS_THREAD = 1,
|
||||
@ -589,6 +591,15 @@ struct SceKernelAllocMemBlockOpt
|
||||
|
||||
// Thread Manager definitions (threads)
|
||||
|
||||
enum
|
||||
{
|
||||
SCE_KERNEL_ATTR_TH_FIFO = 0,
|
||||
SCE_KERNEL_ATTR_TH_PRIO = 0x2000,
|
||||
|
||||
SCE_KERNEL_ATTR_SINGLE = 0, // Event Flag only
|
||||
SCE_KERNEL_ATTR_MULTI = 0x1000, // Event Flag only
|
||||
};
|
||||
|
||||
using SceKernelThreadEntry = s32(u32 argSize, vm::ptr<void> pArgBlock);
|
||||
|
||||
struct SceKernelThreadOptParam
|
||||
@ -727,78 +738,6 @@ struct SceKernelEventFlagInfo
|
||||
le_t<s32> numWaitThreads;
|
||||
};
|
||||
|
||||
struct psv_event_flag_t
|
||||
{
|
||||
const std::string name; // IPC Name
|
||||
|
||||
atomic_t<u32> ref{ 0x80000000 }; // IPC Ref Counter
|
||||
|
||||
const u32 attr; // Event Flag Attributes
|
||||
const u32 init; // Event Flag Init Pattern
|
||||
|
||||
atomic_t<u32> pattern; // Event Flag Pattern
|
||||
|
||||
std::mutex mutex;
|
||||
|
||||
sleep_queue<cpu_thread> sq;
|
||||
|
||||
psv_event_flag_t(const char* name, u32 attr, u32 pattern)
|
||||
: name(name)
|
||||
, attr(attr)
|
||||
, init(pattern)
|
||||
, pattern(pattern)
|
||||
{
|
||||
}
|
||||
|
||||
// Wakeup all waiters to return SCE_KERNEL_ERROR_WAIT_DELETE
|
||||
void destroy()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
const u32 pattern = this->pattern;
|
||||
|
||||
for (auto& thread : sq)
|
||||
{
|
||||
static_cast<ARMv7Thread&>(*thread).GPR[0] = SCE_KERNEL_ERROR_WAIT_DELETE;
|
||||
static_cast<ARMv7Thread&>(*thread).GPR[1] = pattern;
|
||||
thread->state += cpu_state::signal;
|
||||
thread->notify();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline bool event_flag_test(u32 value, u32 pattern, u32 mode)
|
||||
{
|
||||
if (mode & SCE_KERNEL_EVF_WAITMODE_OR)
|
||||
{
|
||||
return (value & pattern) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (value & pattern) == pattern;
|
||||
}
|
||||
}
|
||||
|
||||
inline void event_flag_try_poll(u32& value, u32 pattern, u32 mode)
|
||||
{
|
||||
if (mode & ~7 || (mode & 6) == 6)
|
||||
{
|
||||
throw EXCEPTION("Unknown mode (0x%x)", mode);
|
||||
}
|
||||
|
||||
if (event_flag_test(value, pattern, mode))
|
||||
{
|
||||
if (mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_ALL)
|
||||
{
|
||||
value = 0;
|
||||
}
|
||||
else if (mode & SCE_KERNEL_EVF_WAITMODE_CLEAR_PAT)
|
||||
{
|
||||
value &= ~pattern;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Thread Manager definitions (semaphores)
|
||||
|
||||
struct SceKernelSemaOptParam
|
||||
@ -818,18 +757,18 @@ struct SceKernelSemaInfo
|
||||
le_t<s32> numWaitThreads;
|
||||
};
|
||||
|
||||
struct psv_semaphore_t
|
||||
struct psp2_semaphore
|
||||
{
|
||||
const std::string name; // IPC Name
|
||||
|
||||
atomic_t<u32> ref{ 0x80000000 }; // IPC Ref Counter
|
||||
atomic_t<u32> ref{}; // IPC Ref Counter
|
||||
|
||||
const u32 attr;
|
||||
const s32 max;
|
||||
|
||||
atomic_t<s32> count;
|
||||
|
||||
psv_semaphore_t(const char* name, u32 attr, s32 count, s32 max)
|
||||
psp2_semaphore(const char* name, u32 attr, s32 count, s32 max)
|
||||
: name(name)
|
||||
, attr(attr)
|
||||
, max(max)
|
||||
@ -858,17 +797,17 @@ struct SceKernelMutexInfo
|
||||
le_t<s32> numWaitThreads;
|
||||
};
|
||||
|
||||
struct psv_mutex_t
|
||||
struct psp2_mutex
|
||||
{
|
||||
const std::string name; // IPC Name
|
||||
|
||||
atomic_t<u32> ref{ 0x80000000 }; // IPC Ref Counter
|
||||
atomic_t<u32> ref{}; // IPC Ref Counter
|
||||
|
||||
const u32 attr;
|
||||
|
||||
atomic_t<s32> count;
|
||||
|
||||
psv_mutex_t(const char* name, u32 attr, s32 count)
|
||||
psp2_mutex(const char* name, u32 attr, s32 count)
|
||||
: name(name)
|
||||
, attr(attr)
|
||||
, count(count)
|
||||
@ -918,17 +857,17 @@ struct SceKernelCondInfo
|
||||
le_t<u32> numWaitThreads;
|
||||
};
|
||||
|
||||
struct psv_cond_t
|
||||
struct psp2_cond
|
||||
{
|
||||
const std::string name; // IPC Name
|
||||
|
||||
atomic_t<u32> ref{ 0x80000000 }; // IPC Ref Counter
|
||||
atomic_t<u32> ref{}; // IPC Ref Counter
|
||||
|
||||
const u32 attr;
|
||||
|
||||
const std::shared_ptr<psv_mutex_t> mutex;
|
||||
const std::shared_ptr<psp2_mutex> mutex;
|
||||
|
||||
psv_cond_t(const char* name, u32 attr, const std::shared_ptr<psv_mutex_t>& mutex)
|
||||
psp2_cond(const char* name, u32 attr, const std::shared_ptr<psp2_mutex>& mutex)
|
||||
: name(name)
|
||||
, attr(attr)
|
||||
, mutex(mutex)
|
||||
@ -1022,47 +961,3 @@ struct SceIoDirent
|
||||
vm::lptr<void> d_private;
|
||||
le_t<s32> dummy;
|
||||
};
|
||||
|
||||
// Module
|
||||
// Aux
|
||||
|
||||
inline bool ipc_ref_try_dec(u32& ref)
|
||||
{
|
||||
if (ref & 0x7fffffff)
|
||||
{
|
||||
// return true if the last reference is removed and object must be deleted
|
||||
return !--ref;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw EXCEPTION("Unexpected IPC Ref value (0x%x)", ref);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool ipc_ref_try_inc(u32& ref)
|
||||
{
|
||||
if (ref & 0x80000000)
|
||||
{
|
||||
if (!++ref)
|
||||
{
|
||||
throw EXCEPTION("IPC Ref overflow");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool ipc_ref_try_unregister(u32& ref)
|
||||
{
|
||||
if (ref & 0x80000000)
|
||||
{
|
||||
ref &= ~0x80000000;
|
||||
|
||||
// return true if object must be deleted
|
||||
return !ref;
|
||||
}
|
||||
|
||||
throw EXCEPTION("Unexpected IPC Ref value (0x%x)", ref);
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceLibXml.h"
|
||||
|
||||
LOG_CHANNEL(sceLibXml);
|
||||
logs::channel sceLibXml("sceLibXml", logs::level::notice);
|
||||
|
||||
#define REG_FUNC(nid, name) REG_FNID(SceLibXml, nid, name)
|
||||
|
@ -1,12 +1,14 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/ARMv7/ARMv7Thread.h"
|
||||
#include "Emu/ARMv7/ARMv7Callback.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Thread.h"
|
||||
#include "Emu/PSP2/ARMv7Callback.h"
|
||||
|
||||
#include "sceLibc.h"
|
||||
|
||||
LOG_CHANNEL(sceLibc);
|
||||
#include <thread>
|
||||
|
||||
logs::channel sceLibc("sceLibc", logs::level::notice);
|
||||
|
||||
extern fs::file g_tty;
|
||||
|
||||
@ -15,8 +17,6 @@ vm::ptr<void> g_dso;
|
||||
|
||||
std::vector<std::function<void(ARMv7Thread&)>> g_atexit;
|
||||
|
||||
std::mutex g_atexit_mutex;
|
||||
|
||||
std::string arm_fmt(ARMv7Thread& cpu, vm::cptr<char> fmt, u32 g_count)
|
||||
{
|
||||
std::string result;
|
||||
@ -132,7 +132,7 @@ std::string arm_fmt(ARMv7Thread& cpu, vm::cptr<char> fmt, u32 g_count)
|
||||
case 's':
|
||||
{
|
||||
// string
|
||||
const vm::cptr<char> string{ cpu.get_next_gpr_arg(g_count), vm::addr };
|
||||
const vm::cptr<char> string = vm::cast(cpu.get_next_gpr_arg(g_count));
|
||||
|
||||
if (plus_sign || minus_sign || space_sign || number_sign || zero_padding || width || prec) break;
|
||||
|
||||
@ -157,8 +157,6 @@ namespace sce_libc_func
|
||||
{
|
||||
sceLibc.warning("__cxa_atexit(func=*0x%x, arg=*0x%x, dso=*0x%x)", func, arg, dso);
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_atexit_mutex);
|
||||
|
||||
g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Thread& cpu)
|
||||
{
|
||||
func(cpu, arg);
|
||||
@ -169,8 +167,6 @@ namespace sce_libc_func
|
||||
{
|
||||
sceLibc.warning("__aeabi_atexit(arg=*0x%x, func=*0x%x, dso=*0x%x)", arg, func, dso);
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_atexit_mutex);
|
||||
|
||||
g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Thread& cpu)
|
||||
{
|
||||
func(cpu, arg);
|
||||
@ -181,8 +177,6 @@ namespace sce_libc_func
|
||||
{
|
||||
sceLibc.warning("exit()");
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_atexit_mutex);
|
||||
|
||||
CHECK_EMU_STATUS;
|
||||
|
||||
for (auto& func : decltype(g_atexit)(std::move(g_atexit)))
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceLibm.h"
|
||||
|
||||
LOG_CHANNEL(sceLibm);
|
||||
logs::channel sceLibm("sceLibm", logs::level::notice);
|
||||
|
||||
namespace sce_libm_func
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceLibstdcxx.h"
|
||||
|
||||
LOG_CHANNEL(sceLibstdcxx);
|
||||
logs::channel sceLibstdcxx("sceLibstdcxx", logs::level::notice);
|
||||
|
||||
namespace sce_libstdcxx_func
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceLiveArea.h"
|
||||
|
||||
LOG_CHANNEL(sceLiveArea);
|
||||
logs::channel sceLiveArea("sceLiveArea", logs::level::notice);
|
||||
|
||||
s32 sceLiveAreaResourceReplaceAll(vm::cptr<char> dirpath)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceLocation.h"
|
||||
|
||||
LOG_CHANNEL(sceLocation);
|
||||
logs::channel sceLocation("sceLocation", logs::level::notice);
|
||||
|
||||
s32 sceLocationOpen(vm::ptr<u8> handle, SceLocationLocationMethod lmethod, SceLocationHeadingMethod hmethod)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceMd5.h"
|
||||
|
||||
LOG_CHANNEL(sceMd5);
|
||||
logs::channel sceMd5("sceMd5", logs::level::notice);
|
||||
|
||||
s32 sceMd5Digest(vm::cptr<void> plain, u32 len, vm::ptr<u8> digest)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceMotion.h"
|
||||
|
||||
LOG_CHANNEL(sceMotion);
|
||||
logs::channel sceMotion("sceMotion", logs::level::notice);
|
||||
|
||||
s32 sceMotionGetState(vm::ptr<SceMotionState> motionState)
|
||||
{
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
struct SceMotionState
|
||||
{
|
||||
le_t<u32> timestamp;
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceMt19937.h"
|
||||
|
||||
LOG_CHANNEL(sceMt19937);
|
||||
logs::channel sceMt19937("sceMt19937", logs::level::notice);
|
||||
|
||||
s32 sceMt19937Init(vm::ptr<SceMt19937Context> pCtx, u32 seed)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceNet.h"
|
||||
|
||||
LOG_CHANNEL(sceNet);
|
||||
logs::channel sceNet("sceNet", logs::level::notice);
|
||||
|
||||
s32 sceNetSetDnsInfo(vm::ptr<SceNetDnsInfo> info, s32 flags)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceNetCtl.h"
|
||||
|
||||
LOG_CHANNEL(sceNetCtl);
|
||||
logs::channel sceNetCtl("sceNetCtl", logs::level::notice);
|
||||
|
||||
s32 sceNetCtlInit()
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceNgs.h"
|
||||
|
||||
LOG_CHANNEL(sceNgs);
|
||||
logs::channel sceNgs("sceNgs", logs::level::notice);
|
||||
|
||||
s32 sceNgsSystemGetRequiredMemorySize(vm::cptr<SceNgsSystemInitParams> pSynthParams, vm::ptr<u32> pnSize)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceNpBasic.h"
|
||||
|
||||
LOG_CHANNEL(sceNpBasic);
|
||||
logs::channel sceNpBasic("sceNpBasic", logs::level::notice);
|
||||
|
||||
s32 sceNpBasicInit(vm::ptr<void> opt)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceNpCommon.h"
|
||||
|
||||
LOG_CHANNEL(sceNpCommon);
|
||||
logs::channel sceNpCommon("sceNpCommon", logs::level::notice);
|
||||
|
||||
s32 sceNpAuthInit()
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceNpManager.h"
|
||||
|
||||
LOG_CHANNEL(sceNpManager);
|
||||
logs::channel sceNpManager("sceNpManager", logs::level::notice);
|
||||
|
||||
s32 sceNpInit(vm::cptr<SceNpCommunicationConfig> commConf, vm::ptr<SceNpOptParam> opt)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceNpMatching.h"
|
||||
|
||||
LOG_CHANNEL(sceNpMatching);
|
||||
logs::channel sceNpMatching("sceNpMatching", logs::level::notice);
|
||||
|
||||
// Functions
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceNpScore.h"
|
||||
|
||||
LOG_CHANNEL(sceNpScore);
|
||||
logs::channel sceNpScore("sceNpScore", logs::level::notice);
|
||||
|
||||
s32 sceNpScoreInit(s32 threadPriority, s32 cpuAffinityMask, vm::ptr<void> option)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "sceNpUtility.h"
|
||||
|
||||
LOG_CHANNEL(sceNpUtility);
|
||||
logs::channel sceNpUtility("sceNpUtility", logs::level::notice);
|
||||
|
||||
s32 sceNpLookupInit(s32 usesAsync, s32 threadPriority, s32 cpuAffinityMask, vm::ptr<void> option)
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "scePerf.h"
|
||||
|
||||
LOG_CHANNEL(scePerf);
|
||||
logs::channel scePerf("scePerf", logs::level::notice);
|
||||
|
||||
extern u64 get_system_time();
|
||||
|
||||
@ -12,7 +12,7 @@ arm_error_code scePerfArmPmonReset(ARMv7Thread& cpu, s32 threadId)
|
||||
{
|
||||
scePerf.warning("scePerfArmPmonReset(threadId=0x%x)", threadId);
|
||||
|
||||
ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
|
||||
cpu.counters = {};
|
||||
|
||||
@ -23,7 +23,7 @@ arm_error_code scePerfArmPmonSelectEvent(ARMv7Thread& cpu, s32 threadId, u32 cou
|
||||
{
|
||||
scePerf.warning("scePerfArmPmonSelectEvent(threadId=0x%x, counter=0x%x, eventCode=0x%x)", threadId, counter, eventCode);
|
||||
|
||||
ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
|
||||
if (counter >= 6)
|
||||
{
|
||||
@ -72,7 +72,7 @@ arm_error_code scePerfArmPmonStart(ARMv7Thread& cpu, s32 threadId)
|
||||
{
|
||||
scePerf.warning("scePerfArmPmonStart(threadId=0x%x)", threadId);
|
||||
|
||||
ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
@ -81,7 +81,7 @@ arm_error_code scePerfArmPmonStop(ARMv7Thread& cpu, s32 threadId)
|
||||
{
|
||||
scePerf.warning("scePerfArmPmonStop(threadId=0x%x)");
|
||||
|
||||
ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
|
||||
return SCE_OK;
|
||||
}
|
||||
@ -90,7 +90,7 @@ arm_error_code scePerfArmPmonGetCounterValue(ARMv7Thread& cpu, s32 threadId, u32
|
||||
{
|
||||
scePerf.warning("scePerfArmPmonGetCounterValue(threadId=0x%x, counter=%d, pValue=*0x%x)", threadId, counter, pValue);
|
||||
|
||||
ASSERT(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
VERIFY(threadId == SCE_PERF_ARM_PMON_THREAD_ID_SELF);
|
||||
|
||||
if (counter >= 6 && counter != SCE_PERF_ARM_PMON_CYCLE_COUNTER)
|
||||
{
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Emu/ARMv7/ErrorCodes.h"
|
||||
#include "Emu/PSP2/ErrorCodes.h"
|
||||
|
||||
enum ScePerfError : s32
|
||||
{
|
@ -1,10 +1,10 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/ARMv7/ARMv7Module.h"
|
||||
#include "Emu/PSP2/ARMv7Module.h"
|
||||
|
||||
#include "scePgf.h"
|
||||
|
||||
LOG_CHANNEL(scePgf);
|
||||
logs::channel scePgf("scePgf", logs::level::notice);
|
||||
|
||||
#define REG_FUNC(nid, name) REG_FNID(ScePgf, nid, name)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user