mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
ARMv7Callback.h, psv modules initialization fixed
sceLibc: __cxa_atexit, __aeabi_atexit
This commit is contained in:
parent
506951a5a4
commit
509e09c2c5
14 changed files with 251 additions and 58 deletions
18
rpcs3/Emu/ARMv7/ARMv7Callback.h
Normal file
18
rpcs3/Emu/ARMv7/ARMv7Callback.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/ARMv7/PSVFuncList.h"
|
||||
|
||||
namespace vm
|
||||
{
|
||||
template<typename AT, typename RT, typename... T>
|
||||
__forceinline RT _ptr_base<RT(*)(T...), 1, AT>::operator()(ARMv7Context& context, T... args) const
|
||||
{
|
||||
return psv_func_detail::func_caller<RT, T...>::call(context, vm::cast(this->addr()), args...);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename RT, typename... T>
|
||||
__forceinline RT cb_call(ARMv7Context& context, u32 addr, T... args)
|
||||
{
|
||||
return psv_func_detail::func_caller<RT, T...>::call(context, addr, args...);
|
||||
}
|
|
@ -29,7 +29,9 @@ struct ARMv7Context
|
|||
|
||||
void write_pc(u32 value);
|
||||
u32 read_pc();
|
||||
void put_stack_arg(u32 shift, u32 value);
|
||||
u32 get_stack_arg(u32 pos);
|
||||
void fast_call(u32 addr);
|
||||
|
||||
union
|
||||
{
|
||||
|
|
|
@ -20,11 +20,21 @@ u32 ARMv7Context::read_pc()
|
|||
return thread.PC;
|
||||
}
|
||||
|
||||
void ARMv7Context::put_stack_arg(u32 shift, u32 value)
|
||||
{
|
||||
vm::psv::write32(SP + shift, value);
|
||||
}
|
||||
|
||||
u32 ARMv7Context::get_stack_arg(u32 pos)
|
||||
{
|
||||
return vm::psv::read32(SP + sizeof(u32) * (pos - 5));
|
||||
}
|
||||
|
||||
void ARMv7Context::fast_call(u32 addr)
|
||||
{
|
||||
return thread.FastCall(addr);
|
||||
}
|
||||
|
||||
ARMv7Thread::ARMv7Thread()
|
||||
: CPUThread(CPU_THREAD_ARMv7)
|
||||
, context(*this)
|
||||
|
|
|
@ -327,6 +327,10 @@ s32 sceKernelWaitThreadEndCB(u32 threadId, vm::psv::ptr<s32> pExitStatus, vm::ps
|
|||
|
||||
psv_log_base sceLibKernel("sceLibKernel", []()
|
||||
{
|
||||
sceLibKernel.on_load = nullptr;
|
||||
sceLibKernel.on_unload = nullptr;
|
||||
sceLibKernel.on_stop = nullptr;
|
||||
|
||||
//REG_FUNC(0x23EAA62, sceKernelPuts);
|
||||
//REG_FUNC(0xB0335388, sceClibToupper);
|
||||
//REG_FUNC(0x4C5471BC, sceClibTolower);
|
||||
|
|
|
@ -3,29 +3,51 @@
|
|||
#include "Emu/System.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/ARMv7/PSVFuncList.h"
|
||||
#include "Emu/ARMv7/ARMv7Callback.h"
|
||||
|
||||
extern psv_log_base sceLibc;
|
||||
|
||||
vm::psv::ptr<void> g_dso;
|
||||
|
||||
typedef void(*atexit_func_t)(vm::psv::ptr<void>);
|
||||
|
||||
std::vector<std::function<void(ARMv7Context&)>> g_atexit;
|
||||
|
||||
namespace sce_libc_func
|
||||
{
|
||||
void __cxa_atexit()
|
||||
void __cxa_atexit(vm::psv::ptr<atexit_func_t> func, vm::psv::ptr<void> arg, vm::psv::ptr<void> dso)
|
||||
{
|
||||
sceLibc.Todo(__FUNCTION__);
|
||||
Emu.Pause();
|
||||
sceLibc.Error("__cxa_atexit(func=0x%x, arg=0x%x, dso=0x%x)", func, arg, dso);
|
||||
|
||||
g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Context& context)
|
||||
{
|
||||
func(context, arg);
|
||||
});
|
||||
}
|
||||
|
||||
void __aeabi_atexit()
|
||||
void __aeabi_atexit(vm::psv::ptr<void> arg, vm::psv::ptr<atexit_func_t> func, vm::psv::ptr<void> dso)
|
||||
{
|
||||
sceLibc.Todo(__FUNCTION__);
|
||||
Emu.Pause();
|
||||
sceLibc.Error("__aeabi_atexit(arg=0x%x, func=0x%x, dso=0x%x)", arg, func, dso);
|
||||
|
||||
g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Context& context)
|
||||
{
|
||||
func(context, arg);
|
||||
});
|
||||
}
|
||||
|
||||
void exit()
|
||||
void exit(ARMv7Context& context)
|
||||
{
|
||||
sceLibc.Error("exit()");
|
||||
Emu.Pause();
|
||||
|
||||
for (auto func : g_atexit)
|
||||
{
|
||||
func(context);
|
||||
}
|
||||
|
||||
g_atexit.clear();
|
||||
|
||||
sceLibc.Success("Process finished");
|
||||
|
||||
CallAfter([]()
|
||||
{
|
||||
Emu.Stop();
|
||||
|
@ -95,9 +117,11 @@ namespace sce_libc_func
|
|||
LOG_NOTICE(TTY, result);
|
||||
}
|
||||
|
||||
void __cxa_set_dso_handle_main()
|
||||
void __cxa_set_dso_handle_main(vm::psv::ptr<void> dso)
|
||||
{
|
||||
sceLibc.Error("__cxa_set_dso_handle_main()");
|
||||
sceLibc.Error("__cxa_set_dso_handle_main(dso=0x%x)", dso);
|
||||
|
||||
g_dso = dso;
|
||||
}
|
||||
|
||||
void memcpy(vm::psv::ptr<void> dst, vm::psv::ptr<const void> src, u32 size)
|
||||
|
@ -127,6 +151,13 @@ namespace sce_libc_func
|
|||
|
||||
psv_log_base sceLibc("SceLibc", []()
|
||||
{
|
||||
g_dso.set(0);
|
||||
g_atexit.clear();
|
||||
|
||||
sceLibc.on_load = nullptr;
|
||||
sceLibc.on_unload = nullptr;
|
||||
sceLibc.on_stop = nullptr;
|
||||
|
||||
REG_FUNC(0xE4531F85, _Assert);
|
||||
//REG_FUNC(0xE71C5CDE, _Stoul);
|
||||
//REG_FUNC(0x7A5CA6A3, _Stoulx);
|
||||
|
|
|
@ -14,6 +14,10 @@ namespace sce_libm_func
|
|||
|
||||
psv_log_base sceLibm("SceLibm", []()
|
||||
{
|
||||
sceLibm.on_load = nullptr;
|
||||
sceLibm.on_unload = nullptr;
|
||||
sceLibm.on_stop = nullptr;
|
||||
|
||||
//REG_FUNC(0xC73FE76D, _Exp);
|
||||
//REG_FUNC(0xFF4EAE04, _FExp);
|
||||
//REG_FUNC(0xB363D7D4, _LExp);
|
||||
|
|
|
@ -30,6 +30,10 @@ namespace sce_libstdcxx_func
|
|||
|
||||
psv_log_base sceLibstdcxx("SceLibstdcxx", []()
|
||||
{
|
||||
sceLibstdcxx.on_load = nullptr;
|
||||
sceLibstdcxx.on_unload = nullptr;
|
||||
sceLibstdcxx.on_stop = nullptr;
|
||||
|
||||
//REG_FUNC(0x52B0C625, std::bad_typeid::what() const);
|
||||
//REG_FUNC(0x64D7D074, std::bad_typeid::_Doraise() const);
|
||||
//REG_FUNC(0x15FB88E2, std::logic_error::what() const);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "PSVFuncList.h"
|
||||
|
||||
std::vector<psv_func> g_psv_func_list;
|
||||
std::vector<psv_log_base*> g_psv_modules;
|
||||
|
||||
void add_psv_func(psv_func& data)
|
||||
{
|
||||
|
@ -48,33 +49,53 @@ extern psv_log_base sceLibm;
|
|||
extern psv_log_base sceLibstdcxx;
|
||||
extern psv_log_base sceLibKernel;
|
||||
|
||||
void list_known_psv_modules()
|
||||
void initialize_psv_modules()
|
||||
{
|
||||
if (!g_psv_func_list.size())
|
||||
assert(!g_psv_func_list.size() && !g_psv_modules.size());
|
||||
|
||||
// fill module list
|
||||
g_psv_modules.push_back(&sceLibc);
|
||||
g_psv_modules.push_back(&sceLibm);
|
||||
g_psv_modules.push_back(&sceLibstdcxx);
|
||||
g_psv_modules.push_back(&sceLibKernel);
|
||||
|
||||
// setup special functions (without NIDs)
|
||||
psv_func unimplemented;
|
||||
unimplemented.nid = 0;
|
||||
unimplemented.name = "Special function (unimplemented stub)";
|
||||
unimplemented.func.reset(new psv_func_detail::func_binder<void, ARMv7Context&>([](ARMv7Context& context)
|
||||
{
|
||||
// setup special functions (without NIDs)
|
||||
psv_func unimplemented;
|
||||
unimplemented.nid = 0;
|
||||
unimplemented.name = "Special function (unimplemented stub)";
|
||||
unimplemented.func.reset(new psv_func_detail::func_binder<void, ARMv7Context&>([](ARMv7Context& context)
|
||||
{
|
||||
context.thread.m_last_syscall = vm::psv::read32(context.thread.PC + 4);
|
||||
throw "Unimplemented function executed";
|
||||
}));
|
||||
g_psv_func_list.push_back(unimplemented);
|
||||
context.thread.m_last_syscall = vm::psv::read32(context.thread.PC + 4);
|
||||
throw "Unimplemented function executed";
|
||||
}));
|
||||
g_psv_func_list.push_back(unimplemented);
|
||||
|
||||
psv_func hle_return;
|
||||
hle_return.nid = 1;
|
||||
hle_return.name = "Special function (return from HLE)";
|
||||
hle_return.func.reset(new psv_func_detail::func_binder<void, ARMv7Context&>([](ARMv7Context& context)
|
||||
{
|
||||
context.thread.FastStop();
|
||||
}));
|
||||
g_psv_func_list.push_back(hle_return);
|
||||
psv_func hle_return;
|
||||
hle_return.nid = 1;
|
||||
hle_return.name = "Special function (return from HLE)";
|
||||
hle_return.func.reset(new psv_func_detail::func_binder<void, ARMv7Context&>([](ARMv7Context& context)
|
||||
{
|
||||
context.thread.FastStop();
|
||||
}));
|
||||
g_psv_func_list.push_back(hle_return);
|
||||
|
||||
sceLibc.Init();
|
||||
sceLibm.Init();
|
||||
sceLibstdcxx.Init();
|
||||
sceLibKernel.Init();
|
||||
// load functions
|
||||
for (auto module : g_psv_modules)
|
||||
{
|
||||
module->Init();
|
||||
}
|
||||
}
|
||||
|
||||
void finalize_psv_modules()
|
||||
{
|
||||
for (auto module : g_psv_modules)
|
||||
{
|
||||
if (module->on_stop)
|
||||
{
|
||||
module->on_stop();
|
||||
}
|
||||
}
|
||||
|
||||
g_psv_func_list.clear();
|
||||
g_psv_modules.clear();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@ class psv_log_base : public LogBase
|
|||
std::string m_name;
|
||||
void(*m_init_func)();
|
||||
|
||||
public:
|
||||
std::function<void()> on_load;
|
||||
std::function<void()> on_unload;
|
||||
std::function<void()> on_stop;
|
||||
|
||||
public:
|
||||
psv_log_base(const std::string& name, void(*init_func)())
|
||||
: m_name(name)
|
||||
|
@ -422,6 +427,8 @@ namespace psv_func_detail
|
|||
ARG_STACK,
|
||||
};
|
||||
|
||||
static const auto FIXED_STACK_FRAME_SIZE = 0x100; // described in CB_FUNC.h
|
||||
|
||||
template<typename T, bind_arg_type type, int g_count, int f_count, int v_count>
|
||||
struct bind_arg;
|
||||
|
||||
|
@ -430,10 +437,15 @@ namespace psv_func_detail
|
|||
{
|
||||
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_GENERAL");
|
||||
|
||||
static __forceinline T func(ARMv7Context& context)
|
||||
__forceinline static T get_arg(ARMv7Context& context)
|
||||
{
|
||||
return cast_from_armv7_gpr<T>(context.GPR[g_count - 1]);
|
||||
}
|
||||
|
||||
__forceinline static void put_arg(ARMv7Context& context, const T& arg)
|
||||
{
|
||||
context.GPR[g_count - 1] = cast_to_armv7_gpr<T>(arg);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int g_count, int f_count, int v_count>
|
||||
|
@ -442,7 +454,11 @@ namespace psv_func_detail
|
|||
static_assert(f_count <= 0, "TODO: Unsupported argument type (float)");
|
||||
static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_FLOAT");
|
||||
|
||||
static __forceinline T func(ARMv7Context& context)
|
||||
__forceinline static T get_arg(ARMv7Context& context)
|
||||
{
|
||||
}
|
||||
|
||||
__forceinline static void put_arg(ARMv7Context& context, const T& arg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -453,7 +469,11 @@ namespace psv_func_detail
|
|||
static_assert(v_count <= 0, "TODO: Unsupported argument type (vector)");
|
||||
static_assert(std::is_same<T, u128>::value, "Invalid function argument type for ARG_VECTOR");
|
||||
|
||||
static __forceinline T func(ARMv7Context& context)
|
||||
__forceinline static T get_arg(ARMv7Context& context)
|
||||
{
|
||||
}
|
||||
|
||||
__forceinline static void put_arg(ARMv7Context& context, const T& arg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -465,11 +485,19 @@ namespace psv_func_detail
|
|||
static_assert(v_count <= 0, "TODO: Unsupported stack argument type (vector)");
|
||||
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_STACK");
|
||||
|
||||
static __forceinline T func(ARMv7Context& context)
|
||||
__forceinline static T get_arg(ARMv7Context& context)
|
||||
{
|
||||
// TODO: check
|
||||
const u32 res = context.get_stack_arg(g_count);
|
||||
return cast_from_armv7_gpr<T>(res);
|
||||
return cast_from_armv7_gpr<T>(context.get_stack_arg(g_count));
|
||||
}
|
||||
|
||||
__forceinline static void put_arg(ARMv7Context& context, const T& arg)
|
||||
{
|
||||
// TODO: check
|
||||
const int stack_pos = (g_count - 5) * 4 - FIXED_STACK_FRAME_SIZE;
|
||||
static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)");
|
||||
|
||||
context.write_stack_arg(stack_pos, cast_to_armv7_gpr<T>(arg));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -481,7 +509,12 @@ namespace psv_func_detail
|
|||
static_assert(type == ARG_GENERAL, "Wrong use of bind_result template");
|
||||
static_assert(sizeof(T) <= 4, "Invalid function result type for ARG_GENERAL");
|
||||
|
||||
static __forceinline void func(ARMv7Context& context, const T& result)
|
||||
__forceinline static T get_result(ARMv7Context& context)
|
||||
{
|
||||
return cast_from_armv7_gpr<T>(context.GPR[0]);
|
||||
}
|
||||
|
||||
__forceinline static void put_result(ARMv7Context& context, const T& result)
|
||||
{
|
||||
context.GPR[0] = cast_to_armv7_gpr<T>(result);
|
||||
}
|
||||
|
@ -492,7 +525,7 @@ namespace psv_func_detail
|
|||
//{
|
||||
// static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT");
|
||||
|
||||
// static __forceinline void func(ARMv7Context& context, const T& result)
|
||||
// static __forceinline void put_result(ARMv7Context& context, const T& result)
|
||||
// {
|
||||
// }
|
||||
//};
|
||||
|
@ -502,11 +535,21 @@ namespace psv_func_detail
|
|||
//{
|
||||
// static_assert(std::is_same<T, u128>::value, "Invalid function result type for ARG_VECTOR");
|
||||
|
||||
// static __forceinline void func(ARMv7Context& context, const T& result)
|
||||
// static __forceinline void put_result(ARMv7Context& context, const T& result)
|
||||
// {
|
||||
// }
|
||||
//};
|
||||
|
||||
template<typename RT>
|
||||
struct result_type
|
||||
{
|
||||
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
|
||||
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
|
||||
static const bool is_float = std::is_floating_point<RT>::value;
|
||||
static const bool is_vector = std::is_same<RT, u128>::value;
|
||||
static const bind_arg_type value = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
|
||||
};
|
||||
|
||||
template <typename RT, typename F, typename Tuple, bool Done, int Total, int... N>
|
||||
struct call_impl
|
||||
{
|
||||
|
@ -554,18 +597,35 @@ namespace psv_func_detail
|
|||
const int f = f_count + (is_float ? 1 : 0);
|
||||
const int v = v_count + (is_vector ? 1 : 0);
|
||||
|
||||
return std::tuple_cat(std::tuple<T>(bind_arg<T, t, g, f, v>::func(context)), iterate<g, f, v, A...>(context));
|
||||
return std::tuple_cat(std::tuple<T>(bind_arg<T, t, g, f, v>::get_arg(context)), iterate<g, f, v, A...>(context));
|
||||
}
|
||||
|
||||
template<typename RT>
|
||||
struct result_type
|
||||
template<int g_count, int f_count, int v_count>
|
||||
__forceinline static bool put_func_args(ARMv7Context& context)
|
||||
{
|
||||
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
|
||||
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
|
||||
static const bool is_float = std::is_floating_point<RT>::value;
|
||||
static const bool is_vector = std::is_same<RT, u128>::value;
|
||||
static const bind_arg_type value = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
|
||||
};
|
||||
// terminator
|
||||
return false;
|
||||
}
|
||||
|
||||
template<int g_count, int f_count, int v_count, typename T1, typename... T>
|
||||
__forceinline static bool put_func_args(ARMv7Context& context, T1 arg, T... args)
|
||||
{
|
||||
static_assert(!std::is_pointer<T1>::value, "Invalid callback argument type (pointer)");
|
||||
static_assert(!std::is_reference<T1>::value, "Invalid callback argument type (reference)");
|
||||
// TODO: check calculations
|
||||
const bool is_float = std::is_floating_point<T>::value;
|
||||
const bool is_vector = std::is_same<T, u128>::value;
|
||||
const bind_arg_type t = is_float
|
||||
? ((f_count >= 4) ? ARG_STACK : ARG_FLOAT)
|
||||
: (is_vector ? ((v_count >= 4) ? ARG_STACK : ARG_VECTOR) : ((g_count >= 4) ? ARG_STACK : ARG_GENERAL));
|
||||
const int g = g_count + (is_float || is_vector ? 0 : 1);
|
||||
const int f = f_count + (is_float ? 1 : 0);
|
||||
const int v = v_count + (is_vector ? 1 : 0);
|
||||
|
||||
bind_arg<T1, t, g, f, v>::put_arg(context, arg);
|
||||
// return true if stack was used
|
||||
return put_func_args<g, f, v>(context, args...) || (t == ARG_STACK);
|
||||
}
|
||||
|
||||
template<typename RT, typename... T>
|
||||
class func_binder;
|
||||
|
@ -623,7 +683,7 @@ namespace psv_func_detail
|
|||
|
||||
virtual void operator()(ARMv7Context& context)
|
||||
{
|
||||
bind_result<RT, result_type<RT>::value>::func(context, call<RT>(m_call, iterate<0, 0, 0, T...>(context)));
|
||||
bind_result<RT, result_type<RT>::value>::put_result(context, call<RT>(m_call, iterate<0, 0, 0, T...>(context)));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -642,7 +702,36 @@ namespace psv_func_detail
|
|||
|
||||
virtual void operator()(ARMv7Context& context)
|
||||
{
|
||||
bind_result<RT, result_type<RT>::value>::func(context, call<RT>(m_call, std::tuple_cat(std::tuple<ARMv7Context&>(context), iterate<0, 0, 0, T...>(context))));
|
||||
bind_result<RT, result_type<RT>::value>::put_result(context, call<RT>(m_call, std::tuple_cat(std::tuple<ARMv7Context&>(context), iterate<0, 0, 0, T...>(context))));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RT, typename... T>
|
||||
struct func_caller
|
||||
{
|
||||
__forceinline static RT call(ARMv7Context& context, u32 addr, T... args)
|
||||
{
|
||||
func_caller<void, T...>::call(context, addr, args...);
|
||||
|
||||
return bind_result<RT, result_type<RT>::value>::get_result(context);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... T>
|
||||
struct func_caller<void, T...>
|
||||
{
|
||||
__forceinline static void call(ARMv7Context& context, u32 addr, T... args)
|
||||
{
|
||||
if (put_func_args<0, 0, 0, T...>(context, args...))
|
||||
{
|
||||
context.SP -= FIXED_STACK_FRAME_SIZE;
|
||||
context.fast_call(addr);
|
||||
context.SP += FIXED_STACK_FRAME_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.fast_call(addr);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -673,4 +762,5 @@ psv_func* get_psv_func_by_nid(u32 nid);
|
|||
u32 get_psv_func_index(psv_func* func);
|
||||
|
||||
void execute_psv_func_by_index(ARMv7Context& context, u32 index);
|
||||
void list_known_psv_modules();
|
||||
void initialize_psv_modules();
|
||||
void finalize_psv_modules();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
class CPUThread;
|
||||
struct ARMv7Context;
|
||||
|
||||
namespace vm
|
||||
{
|
||||
|
@ -332,9 +333,11 @@ namespace vm
|
|||
public:
|
||||
typedef RT(*type)(T...);
|
||||
|
||||
RT operator()(CPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified CPU thread context
|
||||
RT operator()(CPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified PPU thread context
|
||||
|
||||
RT operator()(T... args) const; // defined in CB_FUNC.h, call using current CPU thread context
|
||||
RT operator()(ARMv7Context& context, T... args) const; // defined in ARMv7Callback.h, passing context is mandatory
|
||||
|
||||
RT operator()(T... args) const; // defined in CB_FUNC.h, call using current PPU thread context
|
||||
|
||||
AT addr() const
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Emu/System.h"
|
||||
|
||||
#include "Emu/GameInfo.h"
|
||||
#include "Emu/ARMv7/PSVFuncList.h"
|
||||
#include "Emu/SysCalls/Static.h"
|
||||
#include "Emu/SysCalls/ModuleManager.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
|
@ -361,6 +362,7 @@ void Emulator::Stop()
|
|||
|
||||
LOG_NOTICE(HLE, "All threads stopped...");
|
||||
|
||||
finalize_psv_modules();
|
||||
m_rsx_callback = 0;
|
||||
|
||||
// TODO: check finalization order
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace loader
|
|||
case MACHINE_MIPS: break;
|
||||
case MACHINE_ARM:
|
||||
{
|
||||
list_known_psv_modules();
|
||||
initialize_psv_modules();
|
||||
|
||||
auto armv7_thr_stop_data = vm::psv::ptr<u32>::make(Memory.PSV.RAM.AllocAlign(3 * 4));
|
||||
armv7_thr_stop_data[0] = 0xf870; // HACK instruction (Thumb)
|
||||
|
|
|
@ -266,6 +266,7 @@
|
|||
<ClInclude Include="Crypto\unself.h" />
|
||||
<ClInclude Include="Crypto\utils.h" />
|
||||
<ClInclude Include="define_new_memleakdetect.h" />
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7Callback.h" />
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7Context.h" />
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7Decoder.h" />
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7DisAsm.h" />
|
||||
|
|
|
@ -1285,5 +1285,8 @@
|
|||
<ClInclude Include="Emu\ARMv7\ARMv7Context.h">
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7Callback.h">
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Add table
Reference in a new issue