mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
commit
31bf130b1c
34 changed files with 1014 additions and 853 deletions
|
@ -50,9 +50,9 @@ namespace Log
|
|||
|
||||
enum LogSeverity : u32
|
||||
{
|
||||
Success = 0,
|
||||
Notice,
|
||||
Notice = 0,
|
||||
Warning,
|
||||
Success,
|
||||
Error,
|
||||
};
|
||||
|
||||
|
|
|
@ -465,7 +465,7 @@ typedef ucontext_t x64_context;
|
|||
|
||||
#define X64REG(context, reg) (darwin_x64reg(context, reg))
|
||||
#define XMMREG(context, reg) (reinterpret_cast<u128*>(&(context)->uc_mcontext->__fs.__fpu_xmm0[reg]))
|
||||
#define EFLAGS(context) ((context)->uc_mcontext->__ss.__eflags)
|
||||
#define EFLAGS(context) ((context)->uc_mcontext->__ss.__rflags)
|
||||
|
||||
uint64_t* darwin_x64reg(x64_context *context, int reg)
|
||||
{
|
||||
|
@ -832,7 +832,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
|||
return false;
|
||||
}
|
||||
|
||||
memcpy(vm::get_priv_ptr(addr), XMMREG(context, reg - X64R_XMM0), 16);
|
||||
memcpy(vm::priv_ptr(addr), XMMREG(context, reg - X64R_XMM0), 16);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -842,7 +842,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
|||
return false;
|
||||
}
|
||||
|
||||
memcpy(vm::get_priv_ptr(addr), ®_value, d_size);
|
||||
memcpy(vm::priv_ptr(addr), ®_value, d_size);
|
||||
break;
|
||||
}
|
||||
case X64OP_MOVS:
|
||||
|
@ -867,7 +867,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
|||
|
||||
// copy data
|
||||
memcpy(&value, (void*)RSI(context), d_size);
|
||||
memcpy(vm::get_priv_ptr(a_addr), &value, d_size);
|
||||
memcpy(vm::priv_ptr(a_addr), &value, d_size);
|
||||
|
||||
// shift pointers
|
||||
if (EFLAGS(context) & 0x400 /* direction flag */)
|
||||
|
@ -925,7 +925,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
|||
while (a_addr >> 12 == addr >> 12)
|
||||
{
|
||||
// fill data with value
|
||||
memcpy(vm::get_priv_ptr(a_addr), &value, d_size);
|
||||
memcpy(vm::priv_ptr(a_addr), &value, d_size);
|
||||
|
||||
// shift pointers
|
||||
if (EFLAGS(context) & 0x400 /* direction flag */)
|
||||
|
@ -966,10 +966,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
|||
|
||||
switch (d_size)
|
||||
{
|
||||
case 1: reg_value = vm::get_priv_ref<atomic_le_t<u8>>(addr).exchange((u8)reg_value); break;
|
||||
case 2: reg_value = vm::get_priv_ref<atomic_le_t<u16>>(addr).exchange((u16)reg_value); break;
|
||||
case 4: reg_value = vm::get_priv_ref<atomic_le_t<u32>>(addr).exchange((u32)reg_value); break;
|
||||
case 8: reg_value = vm::get_priv_ref<atomic_le_t<u64>>(addr).exchange((u64)reg_value); break;
|
||||
case 1: reg_value = vm::priv_ref<atomic_le_t<u8>>(addr).exchange((u8)reg_value); break;
|
||||
case 2: reg_value = vm::priv_ref<atomic_le_t<u16>>(addr).exchange((u16)reg_value); break;
|
||||
case 4: reg_value = vm::priv_ref<atomic_le_t<u32>>(addr).exchange((u32)reg_value); break;
|
||||
case 8: reg_value = vm::priv_ref<atomic_le_t<u64>>(addr).exchange((u64)reg_value); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
|
@ -989,10 +989,10 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
|||
|
||||
switch (d_size)
|
||||
{
|
||||
case 1: old_value = vm::get_priv_ref<atomic_le_t<u8>>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break;
|
||||
case 2: old_value = vm::get_priv_ref<atomic_le_t<u16>>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break;
|
||||
case 4: old_value = vm::get_priv_ref<atomic_le_t<u32>>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break;
|
||||
case 8: old_value = vm::get_priv_ref<atomic_le_t<u64>>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break;
|
||||
case 1: old_value = vm::priv_ref<atomic_le_t<u8>>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break;
|
||||
case 2: old_value = vm::priv_ref<atomic_le_t<u16>>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break;
|
||||
case 4: old_value = vm::priv_ref<atomic_le_t<u32>>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break;
|
||||
case 8: old_value = vm::priv_ref<atomic_le_t<u64>>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "PPCThread.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
|
||||
PPCThread* GetCurrentPPCThread()
|
||||
{
|
||||
CPUThread* thread = GetCurrentCPUThread();
|
||||
|
||||
if(!thread || (thread->GetType() != CPU_THREAD_PPU && thread->GetType() != CPU_THREAD_SPU && thread->GetType() != CPU_THREAD_RAW_SPU))
|
||||
{
|
||||
throw std::string("GetCurrentPPCThread: bad thread");
|
||||
}
|
||||
|
||||
return (PPCThread*)thread;
|
||||
}
|
||||
|
||||
PPCThread::PPCThread(CPUThreadType type) : CPUThread(type)
|
||||
{
|
||||
}
|
||||
|
||||
PPCThread::~PPCThread()
|
||||
{
|
||||
}
|
||||
|
||||
void PPCThread::DoReset()
|
||||
{
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#pragma once
|
||||
#include "Emu/CPU/CPUThread.h"
|
||||
|
||||
class PPCThread : public CPUThread
|
||||
{
|
||||
public:
|
||||
virtual std::string GetThreadName() const
|
||||
{
|
||||
return fmt::format("%s[0x%08x]", GetFName(), PC);
|
||||
}
|
||||
|
||||
protected:
|
||||
PPCThread(CPUThreadType type);
|
||||
|
||||
public:
|
||||
virtual ~PPCThread();
|
||||
|
||||
protected:
|
||||
virtual void DoReset() override;
|
||||
};
|
||||
|
||||
PPCThread* GetCurrentPPCThread();
|
|
@ -652,22 +652,53 @@ namespace PPU_instr
|
|||
r12, r13, r14, r15, r16, r17, r18, r19, r20, r21,
|
||||
r22, r23, r24, r25, r26, r27, r28, r29, r30, r31
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
cr0, cr1, cr2, cr3, cr4, cr5, cr6, cr7
|
||||
};
|
||||
}
|
||||
|
||||
namespace implicts
|
||||
{
|
||||
using namespace lists;
|
||||
|
||||
//static auto LIS = std::bind(ADDIS, std::placeholders::_1, r0, std::placeholders::_2);
|
||||
//static auto LI = std::bind(ADDI, std::placeholders::_1, r0, std::placeholders::_2);
|
||||
static auto NOP = std::bind(ORI, r0, r0, 0);
|
||||
static auto MR = std::bind(OR, std::placeholders::_1, std::placeholders::_2, std::placeholders::_2, false);
|
||||
static auto BLR = std::bind(BCLR, 0x10 | 0x04, 0, 0, 0);
|
||||
static auto BCTR = std::bind(BCCTR, 0x10 | 0x04, 0, 0, 0);
|
||||
static auto BCTRL = std::bind(BCCTR, 0x10 | 0x04, 0, 0, 1);
|
||||
static auto MTCTR = std::bind(MTSPR, (0x1 << 5) | 0x8, std::placeholders::_1);
|
||||
}
|
||||
inline u32 LIS(u32 reg, u32 imm) { return ADDIS(reg, r0, imm); }
|
||||
inline u32 LI_(u32 reg, u32 imm) { return ADDI(reg, r0, imm); }
|
||||
inline u32 NOP() { return ORI(r0, r0, 0); }
|
||||
inline u32 MR(u32 x, u32 y) { return OR(x, y, y, false); }
|
||||
inline u32 BLR() { return BCLR(0x10 | 0x04, 0, 0, 0); }
|
||||
inline u32 BCTR() { return BCCTR(0x10 | 0x04, 0, 0, 0); }
|
||||
inline u32 BCTRL() { return BCCTR(0x10 | 0x04, 0, 0, 1); }
|
||||
inline u32 MFCTR(u32 reg) { return MFSPR(reg, 9 << 5); }
|
||||
inline u32 MTCTR(u32 reg) { return MTSPR(9 << 5, reg); }
|
||||
inline u32 MFLR(u32 reg) { return MFSPR(reg, 8 << 5); }
|
||||
inline u32 MTLR(u32 reg) { return MTSPR(8 << 5, reg); }
|
||||
|
||||
inline u32 BNE(u32 cr, s32 imm) { return BC(4, 2 | cr << 2, imm, 0, 0); }
|
||||
inline u32 BEQ(u32 cr, s32 imm) { return BC(12, 2 | cr << 2, imm, 0, 0); }
|
||||
inline u32 BGT(u32 cr, s32 imm) { return BC(12, 1 | cr << 2, imm, 0, 0); }
|
||||
|
||||
inline u32 BNE(s32 imm) { return BNE(cr0, imm); }
|
||||
inline u32 BEQ(s32 imm) { return BEQ(cr0, imm); }
|
||||
inline u32 BGT(s32 imm) { return BGT(cr0, imm); }
|
||||
|
||||
inline u32 CMPDI(u32 cr, u32 reg, u32 imm) { return CMPI(cr, 1, reg, imm); }
|
||||
inline u32 CMPDI(u32 reg, u32 imm) { return CMPDI(cr0, reg, imm); }
|
||||
|
||||
inline u32 CMPWI(u32 cr, u32 reg, u32 imm) { return CMPI(cr, 0, reg, imm); }
|
||||
inline u32 CMPWI(u32 reg, u32 imm) { return CMPWI(cr0, reg, imm); }
|
||||
|
||||
inline u32 CMPLDI(u32 cr, u32 reg, u32 imm) { return CMPLI(cr, 1, reg, imm); }
|
||||
inline u32 CMPLDI(u32 reg, u32 imm) { return CMPLDI(cr0, reg, imm); }
|
||||
|
||||
inline u32 CMPLWI(u32 cr, u32 reg, u32 imm) { return CMPLI(cr, 0, reg, imm); }
|
||||
inline u32 CMPLWI(u32 reg, u32 imm) { return CMPLWI(cr0, reg, imm); }
|
||||
|
||||
inline u32 EXTRDI(u32 x, u32 y, u32 n, u32 b) { return RLDICL(x, y, b + n, 64 - b, false); }
|
||||
inline u32 SRDI(u32 x, u32 y, u32 n) { return RLDICL(x, y, 64 - n, n, false); }
|
||||
inline u32 CLRLDI(u32 x, u32 y, u32 n) { return RLDICL(x, y, 0, n, false); }
|
||||
}
|
||||
|
||||
using namespace lists;
|
||||
using namespace implicts;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "PPUInstrTable.h"
|
||||
/*#include "PPUInstrTable.h"
|
||||
#include "Loader/ELF64.h"
|
||||
/*
|
||||
|
||||
enum ArgType
|
||||
{
|
||||
ARG_ERR = 0,
|
||||
|
|
|
@ -19,14 +19,14 @@ extern void ppu_free_tls(u32 thread);
|
|||
|
||||
PPUThread& GetCurrentPPUThread()
|
||||
{
|
||||
PPCThread* thread = GetCurrentPPCThread();
|
||||
CPUThread* thread = GetCurrentCPUThread();
|
||||
|
||||
if(!thread || thread->GetType() != CPU_THREAD_PPU) throw std::string("GetCurrentPPUThread: bad thread");
|
||||
|
||||
return *(PPUThread*)thread;
|
||||
}
|
||||
|
||||
PPUThread::PPUThread() : PPCThread(CPU_THREAD_PPU)
|
||||
PPUThread::PPUThread() : CPUThread(CPU_THREAD_PPU)
|
||||
{
|
||||
owned_mutexes = 0;
|
||||
Reset();
|
||||
|
@ -39,8 +39,6 @@ PPUThread::~PPUThread()
|
|||
|
||||
void PPUThread::DoReset()
|
||||
{
|
||||
PPCThread::DoReset();
|
||||
|
||||
//reset regs
|
||||
memset(VPR, 0, sizeof(VPR));
|
||||
memset(FPR, 0, sizeof(FPR));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include "Emu/Cell/Common.h"
|
||||
#include "Emu/Cell/PPCThread.h"
|
||||
#include "Emu/CPU/CPUThread.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
|
||||
enum
|
||||
|
@ -467,7 +467,7 @@ struct FPRdouble
|
|||
static int Cmp(PPCdouble a, PPCdouble b);
|
||||
};
|
||||
|
||||
class PPUThread : public PPCThread
|
||||
class PPUThread : public CPUThread
|
||||
{
|
||||
public:
|
||||
PPCdouble FPR[32]; //Floating Point Register
|
||||
|
|
|
@ -47,7 +47,7 @@ bool RawSPUThread::Read32(const u32 addr, u32* value)
|
|||
|
||||
case SPU_MBox_Status_offs:
|
||||
{
|
||||
*value = (SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8);
|
||||
*value = (SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8) | (SPU.Out_IntrMBox.GetCount() << 16);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
SPUThread& GetCurrentSPUThread()
|
||||
{
|
||||
PPCThread* thread = GetCurrentPPCThread();
|
||||
CPUThread* thread = GetCurrentCPUThread();
|
||||
|
||||
if(!thread || (thread->GetType() != CPU_THREAD_SPU && thread->GetType() != CPU_THREAD_RAW_SPU))
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ SPUThread& GetCurrentSPUThread()
|
|||
return *(SPUThread*)thread;
|
||||
}
|
||||
|
||||
SPUThread::SPUThread(CPUThreadType type) : PPCThread(type)
|
||||
SPUThread::SPUThread(CPUThreadType type) : CPUThread(type)
|
||||
{
|
||||
assert(type == CPU_THREAD_SPU || type == CPU_THREAD_RAW_SPU);
|
||||
|
||||
|
@ -73,10 +73,8 @@ void SPUThread::Task()
|
|||
|
||||
void SPUThread::DoReset()
|
||||
{
|
||||
PPCThread::DoReset();
|
||||
|
||||
//reset regs
|
||||
memset(GPR, 0, sizeof(u128) * 128);
|
||||
memset(GPR, 0, sizeof(GPR));
|
||||
}
|
||||
|
||||
void SPUThread::InitRegs()
|
||||
|
@ -412,7 +410,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs)
|
|||
{
|
||||
vm::reservation_op(vm::cast(ea), 128, [this, tag, lsa, ea]()
|
||||
{
|
||||
memcpy(vm::get_priv_ptr(vm::cast(ea)), vm::get_ptr(ls_offset + lsa), 128);
|
||||
memcpy(vm::priv_ptr(vm::cast(ea)), vm::get_ptr(ls_offset + lsa), 128);
|
||||
});
|
||||
|
||||
if (op == MFC_PUTLLUC_CMD)
|
||||
|
@ -568,7 +566,7 @@ void SPUThread::WriteChannel(u32 ch, const u128& r)
|
|||
return;
|
||||
}
|
||||
|
||||
//if (Ini.HLELogging.GetValue())
|
||||
if (Ini.HLELogging.GetValue())
|
||||
{
|
||||
LOG_WARNING(Log::SPU, "sys_spu_thread_throw_event(spup=%d, data0=0x%x, data1=0x%x)", spup, v & 0x00ffffff, data);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "Emu/Cell/Common.h"
|
||||
#include "Emu/CPU/CPUThread.h"
|
||||
#include "Emu/Memory/atomic_type.h"
|
||||
#include "PPCThread.h"
|
||||
#include "Emu/SysCalls/lv2/sleep_queue_type.h"
|
||||
#include "Emu/SysCalls/lv2/sys_event.h"
|
||||
#include "Emu/Event.h"
|
||||
|
@ -115,8 +115,6 @@ enum
|
|||
|
||||
struct g_imm_table_struct
|
||||
{
|
||||
//u16 cntb_table[65536];
|
||||
|
||||
__m128i fsmb_table[65536];
|
||||
__m128i fsmh_table[256];
|
||||
__m128i fsm_table[16];
|
||||
|
@ -127,20 +125,8 @@ struct g_imm_table_struct
|
|||
|
||||
g_imm_table_struct()
|
||||
{
|
||||
/*static_assert(offsetof(g_imm_table_struct, cntb_table) == 0, "offsetof(cntb_table) != 0");
|
||||
for (u32 i = 0; i < sizeof(cntb_table) / sizeof(cntb_table[0]); i++)
|
||||
{
|
||||
u32 cnt_low = 0, cnt_high = 0;
|
||||
for (u32 j = 0; j < 8; j++)
|
||||
{
|
||||
cnt_low += (i >> j) & 1;
|
||||
cnt_high += (i >> (j + 8)) & 1;
|
||||
}
|
||||
cntb_table[i] = (cnt_high << 8) | cnt_low;
|
||||
}*/
|
||||
for (u32 i = 0; i < sizeof(fsm_table) / sizeof(fsm_table[0]); i++)
|
||||
{
|
||||
|
||||
for (u32 j = 0; j < 4; j++) mmToU32Ptr(fsm_table[i])[j] = (i & (1 << j)) ? ~0 : 0;
|
||||
}
|
||||
for (u32 i = 0; i < sizeof(fsmh_table) / sizeof(fsmh_table[0]); i++)
|
||||
|
@ -287,7 +273,7 @@ union SPU_SNRConfig_hdr
|
|||
|
||||
struct SpuGroupInfo;
|
||||
|
||||
class SPUThread : public PPCThread
|
||||
class SPUThread : public CPUThread
|
||||
{
|
||||
public:
|
||||
u128 GPR[128]; // General-Purpose Registers
|
||||
|
|
|
@ -264,7 +264,7 @@ namespace vm
|
|||
_reservation_set(addr, true);
|
||||
|
||||
// update memory using privileged access
|
||||
memcpy(vm::get_priv_ptr(addr), data, size);
|
||||
memcpy(vm::priv_ptr(addr), data, size);
|
||||
|
||||
// remove callback to not call it on successful update
|
||||
g_reservation_cb = nullptr;
|
||||
|
@ -362,7 +362,7 @@ namespace vm
|
|||
}
|
||||
|
||||
void* real_addr = vm::get_ptr(addr);
|
||||
void* priv_addr = vm::get_priv_ptr(addr);
|
||||
void* priv_addr = vm::priv_ptr(addr);
|
||||
|
||||
#ifdef _WIN32
|
||||
auto protection = flags & page_writable ? PAGE_READWRITE : (flags & page_readable ? PAGE_READONLY : PAGE_NOACCESS);
|
||||
|
@ -464,7 +464,7 @@ namespace vm
|
|||
}
|
||||
|
||||
void* real_addr = vm::get_ptr(addr);
|
||||
void* priv_addr = vm::get_priv_ptr(addr);
|
||||
void* priv_addr = vm::priv_ptr(addr);
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD old;
|
||||
|
|
|
@ -77,15 +77,15 @@ namespace vm
|
|||
}
|
||||
|
||||
template<typename T = void>
|
||||
T* const get_priv_ptr(u32 addr)
|
||||
T* const priv_ptr(u32 addr)
|
||||
{
|
||||
return reinterpret_cast<T*>(static_cast<u8*>(g_priv_addr) + addr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& get_priv_ref(u32 addr)
|
||||
T& priv_ref(u32 addr)
|
||||
{
|
||||
return *get_priv_ptr<T>(addr);
|
||||
return *priv_ptr<T>(addr);
|
||||
}
|
||||
|
||||
u32 get_addr(const void* real_pointer);
|
||||
|
|
|
@ -214,9 +214,9 @@ namespace vm
|
|||
return vm::get_ptr<T>(vm::cast(m_addr));
|
||||
}
|
||||
|
||||
T* get_priv_ptr() const
|
||||
T* priv_ptr() const
|
||||
{
|
||||
return vm::get_priv_ptr<T>(vm::cast(m_addr));
|
||||
return vm::priv_ptr<T>(vm::cast(m_addr));
|
||||
}
|
||||
|
||||
static const _ptr_base make(const AT& addr)
|
||||
|
@ -248,9 +248,9 @@ namespace vm
|
|||
return vm::get_ptr<void>(vm::cast(m_addr));
|
||||
}
|
||||
|
||||
void* get_priv_ptr() const
|
||||
void* priv_ptr() const
|
||||
{
|
||||
return vm::get_priv_ptr<void>(vm::cast(m_addr));
|
||||
return vm::priv_ptr<void>(vm::cast(m_addr));
|
||||
}
|
||||
|
||||
explicit operator void*() const
|
||||
|
@ -311,9 +311,9 @@ namespace vm
|
|||
return vm::get_ptr<const void>(vm::cast(m_addr));
|
||||
}
|
||||
|
||||
const void* get_priv_ptr() const
|
||||
const void* priv_ptr() const
|
||||
{
|
||||
return vm::get_priv_ptr<const void>(vm::cast(m_addr));
|
||||
return vm::priv_ptr<const void>(vm::cast(m_addr));
|
||||
}
|
||||
|
||||
explicit operator const void*() const
|
||||
|
|
|
@ -53,6 +53,7 @@ extern Module sys_fs;
|
|||
extern Module sys_io;
|
||||
extern Module sys_net;
|
||||
extern Module sysPrxForUser;
|
||||
extern Module sys_libc;
|
||||
|
||||
struct ModuleInfo
|
||||
{
|
||||
|
@ -166,24 +167,27 @@ static const g_module_list[] =
|
|||
{ -1, "cellSysmodule", &cellSysmodule },
|
||||
{ -1, "libmixer", &libmixer },
|
||||
{ -1, "sysPrxForUser", &sysPrxForUser },
|
||||
{ -1, "sys_libc", &sys_libc },
|
||||
};
|
||||
|
||||
void ModuleManager::Init()
|
||||
{
|
||||
if (!initialized)
|
||||
if (initialized)
|
||||
{
|
||||
clear_ppu_functions();
|
||||
|
||||
for (auto& m : g_module_list)
|
||||
{
|
||||
if (m.module)
|
||||
{
|
||||
m.module->Init();
|
||||
}
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
clear_ppu_functions();
|
||||
|
||||
for (auto& m : g_module_list)
|
||||
{
|
||||
if (m.module)
|
||||
{
|
||||
m.module->Init();
|
||||
}
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
ModuleManager::ModuleManager()
|
||||
|
|
|
@ -30,21 +30,29 @@ u32 add_ppu_func_sub(StaticFunc func)
|
|||
return func.index;
|
||||
}
|
||||
|
||||
u32 add_ppu_func_sub(const char group[8], const u64 ops[], const char* name, Module* module, ppu_func_caller func)
|
||||
u32 add_ppu_func_sub(const char group[8], const SearchPatternEntry ops[], const size_t count, const char* name, Module* module, ppu_func_caller func)
|
||||
{
|
||||
char group_name[9] = {};
|
||||
|
||||
if (group)
|
||||
{
|
||||
strcpy_trunc(group_name, group);
|
||||
}
|
||||
|
||||
StaticFunc sf;
|
||||
sf.index = add_ppu_func(ModuleFunc(get_function_id(name), 0, module, func));
|
||||
sf.name = name;
|
||||
sf.group = *(u64*)group;
|
||||
sf.group = *(u64*)group_name;
|
||||
sf.found = 0;
|
||||
|
||||
// TODO: check for self-inclusions, use CRC
|
||||
for (u32 i = 0; ops[i]; i++)
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
SFuncOp op;
|
||||
op.mask = re32((u32)(ops[i] >> 32));
|
||||
op.crc = re32((u32)(ops[i]));
|
||||
if (op.mask) op.crc &= op.mask;
|
||||
SearchPatternEntry op;
|
||||
op.type = ops[i].type;
|
||||
op.data = re32(ops[i].data);
|
||||
op.mask = re32(ops[i].mask);
|
||||
op.num = ops[i].num;
|
||||
assert(!op.mask || (op.data & ~op.mask) == 0);
|
||||
sf.ops.push_back(op);
|
||||
}
|
||||
|
||||
|
@ -166,90 +174,155 @@ u32 get_function_id(const char* name)
|
|||
return (u32&)output[0];
|
||||
}
|
||||
|
||||
void hook_ppu_funcs(u32* base, u32 size)
|
||||
void hook_ppu_func(vm::ptr<u32> base, u32 pos, u32 size)
|
||||
{
|
||||
size /= 4;
|
||||
using namespace PPU_instr;
|
||||
|
||||
for (auto& sub : g_ppu_func_subs)
|
||||
{
|
||||
bool found = true;
|
||||
|
||||
for (u32 k = pos, x = 0; x + 1 <= sub.ops.size(); k++, x++)
|
||||
{
|
||||
if (k >= size)
|
||||
{
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// skip NOP
|
||||
if (base[k].data() == se32(0x60000000))
|
||||
{
|
||||
x--;
|
||||
continue;
|
||||
}
|
||||
|
||||
const u32 data = sub.ops[x].data;
|
||||
const u32 mask = sub.ops[x].mask;
|
||||
|
||||
const bool match = (base[k].data() & mask) == data;
|
||||
|
||||
switch (sub.ops[x].type)
|
||||
{
|
||||
case SPET_MASKED_OPCODE:
|
||||
{
|
||||
// masked pattern
|
||||
if (!match)
|
||||
{
|
||||
found = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SPET_OPTIONAL_MASKED_OPCODE:
|
||||
{
|
||||
// optional masked pattern
|
||||
if (!match)
|
||||
{
|
||||
k--;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SPET_LABEL:
|
||||
{
|
||||
const auto addr = (base + k--).addr();
|
||||
const auto lnum = data;
|
||||
const auto label = sub.labels.find(lnum);
|
||||
|
||||
if (label == sub.labels.end()) // register the label
|
||||
{
|
||||
sub.labels[lnum] = addr;
|
||||
}
|
||||
else if (label->second != addr) // or check registered label
|
||||
{
|
||||
found = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SPET_BRANCH_TO_LABEL:
|
||||
{
|
||||
if (!match)
|
||||
{
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
const auto addr = (base[k].data() & se32(2) ? 0 : (base + k).addr()) + ((s32)base[k] << cntlz32(mask) >> (cntlz32(mask) + 2));
|
||||
const auto lnum = sub.ops[x].num;
|
||||
const auto label = sub.labels.find(lnum);
|
||||
|
||||
if (label == sub.labels.end()) // register the label
|
||||
{
|
||||
sub.labels[lnum] = addr;
|
||||
}
|
||||
else if (label->second != addr) // or check registered label
|
||||
{
|
||||
found = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
//case SPET_BRANCH_TO_FUNC:
|
||||
//{
|
||||
// if (!match)
|
||||
// {
|
||||
// found = false;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// const auto addr = (base[k].data() & se32(2) ? 0 : (base + k).addr()) + ((s32)base[k] << cntlz32(mask) >> (cntlz32(mask) + 2));
|
||||
// const auto nid = sub.ops[x].num;
|
||||
// // TODO: recursive call
|
||||
//}
|
||||
default:
|
||||
{
|
||||
LOG_ERROR(LOADER, "Unknown search pattern type (%d)", sub.ops[x].type);
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
LOG_SUCCESS(LOADER, "Function '%s' hooked (addr=0x%x)", sub.name, (base + pos).addr());
|
||||
sub.found++;
|
||||
base[pos] = HACK(sub.index | EIF_PERFORM_BLR);
|
||||
}
|
||||
|
||||
if (sub.labels.size())
|
||||
{
|
||||
sub.labels.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hook_ppu_funcs(vm::ptr<u32> base, u32 size)
|
||||
{
|
||||
using namespace PPU_instr;
|
||||
|
||||
if (!Ini.HLEHookStFunc.GetValue())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: optimize search
|
||||
for (u32 i = 0; i < size; i++)
|
||||
{
|
||||
for (u32 j = 0; j < g_ppu_func_subs.size(); j++)
|
||||
// skip NOP
|
||||
if (base[i].data() == se32(0x60000000))
|
||||
{
|
||||
if ((base[i] & g_ppu_func_subs[j].ops[0].mask) == g_ppu_func_subs[j].ops[0].crc)
|
||||
{
|
||||
bool found = true;
|
||||
u32 can_skip = 0;
|
||||
for (u32 k = i, x = 0; x + 1 <= g_ppu_func_subs[j].ops.size(); k++, x++)
|
||||
{
|
||||
if (k >= size)
|
||||
{
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// skip NOP
|
||||
if (base[k] == se32(0x60000000))
|
||||
{
|
||||
x--;
|
||||
continue;
|
||||
}
|
||||
|
||||
const u32 mask = g_ppu_func_subs[j].ops[x].mask;
|
||||
const u32 crc = g_ppu_func_subs[j].ops[x].crc;
|
||||
|
||||
if (!mask)
|
||||
{
|
||||
// TODO: define syntax
|
||||
if (crc < 4) // skip various number of instructions that don't match next pattern entry
|
||||
{
|
||||
can_skip += crc;
|
||||
k--; // process this position again
|
||||
}
|
||||
else if (base[k] != crc) // skippable pattern ("optional" instruction), no mask allowed
|
||||
{
|
||||
k--;
|
||||
if (can_skip) // cannot define this behaviour properly
|
||||
{
|
||||
LOG_WARNING(LOADER, "hook_ppu_funcs(): can_skip = %d (unchanged)", can_skip);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (can_skip) // cannot define this behaviour properly
|
||||
{
|
||||
LOG_WARNING(LOADER, "hook_ppu_funcs(): can_skip = %d (set to 0)", can_skip);
|
||||
can_skip = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((base[k] & mask) != crc) // masked pattern
|
||||
{
|
||||
if (can_skip)
|
||||
{
|
||||
can_skip--;
|
||||
}
|
||||
else
|
||||
{
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
can_skip = 0;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
LOG_NOTICE(LOADER, "Function '%s' hooked (addr=0x%x)", g_ppu_func_subs[j].name, vm::get_addr(base + i * 4));
|
||||
g_ppu_func_subs[j].found++;
|
||||
base[i] = re32(0x04000000 | g_ppu_func_subs[j].index | EIF_PERFORM_BLR); // hack
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
hook_ppu_func(base, i, size);
|
||||
}
|
||||
|
||||
// check function groups
|
||||
|
@ -259,6 +332,12 @@ void hook_ppu_funcs(u32* base, u32 size)
|
|||
{
|
||||
const u64 group = g_ppu_func_subs[i].group;
|
||||
|
||||
if (!group)
|
||||
{
|
||||
// skip if group not set
|
||||
continue;
|
||||
}
|
||||
|
||||
enum GroupSearchResult : u32
|
||||
{
|
||||
GSR_SUCCESS = 0, // every function from this group has been found once
|
||||
|
@ -320,17 +399,17 @@ void hook_ppu_funcs(u32* base, u32 size)
|
|||
if (g_ppu_func_subs[j].group == group) g_ppu_func_subs[j].found = 0;
|
||||
}
|
||||
|
||||
char name[9] = "????????";
|
||||
char group_name[9] = {};
|
||||
|
||||
*(u64*)name = group;
|
||||
*(u64*)group_name = group;
|
||||
|
||||
if (res == GSR_SUCCESS)
|
||||
{
|
||||
LOG_SUCCESS(LOADER, "Function group [%s] successfully hooked", std::string(name, 9).c_str());
|
||||
LOG_SUCCESS(LOADER, "Function group [%s] successfully hooked", group_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR(LOADER, "Function group [%s] failed:%s%s", std::string(name, 9).c_str(),
|
||||
LOG_ERROR(LOADER, "Function group [%s] failed:%s%s", group_name,
|
||||
(res & GSR_MISSING ? " missing;" : ""),
|
||||
(res & GSR_EXCESS ? " excess;" : ""));
|
||||
}
|
||||
|
@ -338,6 +417,102 @@ void hook_ppu_funcs(u32* base, u32 size)
|
|||
}
|
||||
}
|
||||
|
||||
bool patch_ppu_import(u32 addr, u32 index)
|
||||
{
|
||||
const auto data = vm::ptr<const u32>::make(addr);
|
||||
|
||||
using namespace PPU_instr;
|
||||
|
||||
// check different patterns:
|
||||
|
||||
if (vm::check_addr(addr, 32) &&
|
||||
(data[0] & 0xffff0000) == LI_(r12, 0) &&
|
||||
(data[1] & 0xffff0000) == ORIS(r12, r12, 0) &&
|
||||
(data[2] & 0xffff0000) == LWZ(r12, r12, 0) &&
|
||||
data[3] == STD(r2, r1, 0x28) &&
|
||||
data[4] == LWZ(r0, r12, 0) &&
|
||||
data[5] == LWZ(r2, r12, 4) &&
|
||||
data[6] == MTCTR(r0) &&
|
||||
data[7] == BCTR())
|
||||
{
|
||||
vm::write32(addr, HACK(index | EIF_SAVE_RTOC | EIF_PERFORM_BLR));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vm::check_addr(addr, 12) &&
|
||||
(data[0] & 0xffff0000) == LI_(r0, 0) &&
|
||||
(data[1] & 0xffff0000) == ORIS(r0, r0, 0) &&
|
||||
(data[2] & 0xfc000003) == B(0, 0, 0))
|
||||
{
|
||||
const auto sub = vm::ptr<const u32>::make(addr + 8 + ((s32)data[2] << 6 >> 8 << 2));
|
||||
|
||||
if (vm::check_addr(sub.addr(), 60) &&
|
||||
sub[0x0] == STDU(r1, r1, -0x80) &&
|
||||
sub[0x1] == STD(r2, r1, 0x70) &&
|
||||
sub[0x2] == MR(r2, r0) &&
|
||||
sub[0x3] == MFLR(r0) &&
|
||||
sub[0x4] == STD(r0, r1, 0x90) &&
|
||||
sub[0x5] == LWZ(r2, r2, 0) &&
|
||||
sub[0x6] == LWZ(r0, r2, 0) &&
|
||||
sub[0x7] == LWZ(r2, r2, 4) &&
|
||||
sub[0x8] == MTCTR(r0) &&
|
||||
sub[0x9] == BCTRL() &&
|
||||
sub[0xa] == LD(r2, r1, 0x70) &&
|
||||
sub[0xb] == ADDI(r1, r1, 0x80) &&
|
||||
sub[0xc] == LD(r0, r1, 0x10) &&
|
||||
sub[0xd] == MTLR(r0) &&
|
||||
sub[0xe] == BLR())
|
||||
{
|
||||
vm::write32(addr, HACK(index | EIF_PERFORM_BLR));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm::check_addr(addr, 64) &&
|
||||
data[0x0] == MFLR(r0) &&
|
||||
data[0x1] == STD(r0, r1, 0x10) &&
|
||||
data[0x2] == STDU(r1, r1, -0x80) &&
|
||||
data[0x3] == STD(r2, r1, 0x70) &&
|
||||
(data[0x4] & 0xffff0000) == LI_(r2, 0) &&
|
||||
(data[0x5] & 0xffff0000) == ORIS(r2, r2, 0) &&
|
||||
data[0x6] == LWZ(r2, r2, 0) &&
|
||||
data[0x7] == LWZ(r0, r2, 0) &&
|
||||
data[0x8] == LWZ(r2, r2, 4) &&
|
||||
data[0x9] == MTCTR(r0) &&
|
||||
data[0xa] == BCTRL() &&
|
||||
data[0xb] == LD(r2, r1, 0x70) &&
|
||||
data[0xc] == ADDI(r1, r1, 0x80) &&
|
||||
data[0xd] == LD(r0, r1, 0x10) &&
|
||||
data[0xe] == MTLR(r0) &&
|
||||
data[0xf] == BLR())
|
||||
{
|
||||
vm::write32(addr, HACK(index | EIF_PERFORM_BLR));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vm::check_addr(addr, 56) &&
|
||||
(data[0x0] & 0xffff0000) == LI_(r12, 0) &&
|
||||
(data[0x1] & 0xffff0000) == ORIS(r12, r12, 0) &&
|
||||
(data[0x2] & 0xffff0000) == LWZ(r12, r12, 0) &&
|
||||
data[0x3] == STD(r2, r1, 0x28) &&
|
||||
data[0x4] == MFLR(r0) &&
|
||||
data[0x5] == STD(r0, r1, 0x20) &&
|
||||
data[0x6] == LWZ(r0, r12, 0) &&
|
||||
data[0x7] == LWZ(r2, r12, 4) &&
|
||||
data[0x8] == MTCTR(r0) &&
|
||||
data[0x9] == BCTRL() &&
|
||||
data[0xa] == LD(r0, r1, 0x20) &&
|
||||
data[0xb] == MTLR(r0) &&
|
||||
data[0xc] == LD(r2, r1, 0x28) &&
|
||||
data[0xd] == BLR())
|
||||
{
|
||||
vm::write32(addr, HACK(index | EIF_PERFORM_BLR));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Module::Module(const char* name, void(*init)())
|
||||
: m_is_loaded(false)
|
||||
, m_name(name)
|
||||
|
|
|
@ -43,19 +43,31 @@ struct ModuleFunc
|
|||
}
|
||||
};
|
||||
|
||||
struct SFuncOp
|
||||
enum : u32
|
||||
{
|
||||
u32 crc;
|
||||
SPET_MASKED_OPCODE,
|
||||
SPET_OPTIONAL_MASKED_OPCODE,
|
||||
SPET_LABEL,
|
||||
SPET_BRANCH_TO_LABEL,
|
||||
SPET_BRANCH_TO_FUNC,
|
||||
};
|
||||
|
||||
struct SearchPatternEntry
|
||||
{
|
||||
u32 type;
|
||||
u32 data;
|
||||
u32 mask;
|
||||
u32 num; // supplement info
|
||||
};
|
||||
|
||||
struct StaticFunc
|
||||
{
|
||||
u32 index;
|
||||
const char* name;
|
||||
std::vector<SFuncOp> ops;
|
||||
std::vector<SearchPatternEntry> ops;
|
||||
u64 group;
|
||||
u32 found;
|
||||
std::unordered_map<u32, u32> labels;
|
||||
};
|
||||
|
||||
class Module : public LogBase
|
||||
|
@ -138,17 +150,26 @@ void clear_ppu_functions();
|
|||
u32 get_function_id(const char* name);
|
||||
|
||||
u32 add_ppu_func_sub(StaticFunc sf);
|
||||
u32 add_ppu_func_sub(const char group[8], const u64 ops[], const char* name, Module* module, ppu_func_caller func);
|
||||
u32 add_ppu_func_sub(const char group[8], const SearchPatternEntry ops[], size_t count, const char* name, Module* module, ppu_func_caller func);
|
||||
|
||||
void hook_ppu_funcs(u32* base, u32 size);
|
||||
void hook_ppu_funcs(vm::ptr<u32> base, u32 size);
|
||||
|
||||
bool patch_ppu_import(u32 addr, u32 index);
|
||||
|
||||
#define REG_FUNC(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &module, bind_func(name)))
|
||||
#define REG_FUNC_FH(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_FORCED_HLE, &module, bind_func(name)))
|
||||
|
||||
#define REG_UNNAMED(module, nid) add_ppu_func(ModuleFunc(0x##nid, 0, &module, bind_func(_nid_##nid)))
|
||||
|
||||
#define REG_SUB(module, group, name, ...) \
|
||||
static const u64 name ## _table[] = {__VA_ARGS__ , 0}; \
|
||||
if (name ## _table[0]) add_ppu_func_sub(group, name ## _table, #name, &module, bind_func(name))
|
||||
#define REG_SUB(module, group, ns, name, ...) \
|
||||
const SearchPatternEntry name##_table[] = {__VA_ARGS__}; \
|
||||
add_ppu_func_sub(group, name##_table, sizeof(name##_table) / sizeof(SearchPatternEntry), #name, &module, bind_func(ns::name))
|
||||
|
||||
#define se_op_all(type, op, sup) []() { s32 XXX = 0; SearchPatternEntry res = { (type), (op), 0, (sup) }; XXX = -1; res.mask = (op) ^ ~res.data; return res; }()
|
||||
#define se_op(op) se_op_all(SPET_MASKED_OPCODE, op, 0)
|
||||
#define se_opt_op(op) se_op_all(SPET_OPTIONAL_MASKED_OPCODE, op, 0)
|
||||
#define se_label(label) { SPET_LABEL, (label) }
|
||||
#define se_br_label(op, label) se_op_all(SPET_BRANCH_TO_LABEL, op, label)
|
||||
#define se_func_call(op, name) se_op_all(SPET_BRANCH_TO_FUNC, op, get_function_id(#name))
|
||||
|
||||
#define UNIMPLEMENTED_FUNC(module) module.Error("%s", __FUNCTION__)
|
||||
|
|
|
@ -168,7 +168,7 @@ bool spursKernel1SelectWorkload(SPUThread & spu) {
|
|||
|
||||
vm::reservation_op(vm::cast(ctxt->spurs.addr()), 128, [&]() {
|
||||
// lock the first 0x80 bytes of spurs
|
||||
auto spurs = ctxt->spurs.get_priv_ptr();
|
||||
auto spurs = ctxt->spurs.priv_ptr();
|
||||
|
||||
// Calculate the contention (number of SPUs used) for each workload
|
||||
u8 contention[CELL_SPURS_MAX_WORKLOAD];
|
||||
|
@ -325,7 +325,7 @@ bool spursKernel2SelectWorkload(SPUThread & spu) {
|
|||
|
||||
vm::reservation_op(vm::cast(ctxt->spurs.addr()), 128, [&]() {
|
||||
// lock the first 0x80 bytes of spurs
|
||||
auto spurs = ctxt->spurs.get_priv_ptr();
|
||||
auto spurs = ctxt->spurs.priv_ptr();
|
||||
|
||||
// Calculate the contention (number of SPUs used) for each workload
|
||||
u8 contention[CELL_SPURS_MAX_WORKLOAD2];
|
||||
|
@ -696,7 +696,7 @@ void spursSysServiceMain(SPUThread & spu, u32 pollStatus) {
|
|||
vm::reservation_acquire(vm::get_ptr(spu.ls_offset + 0x100), vm::cast(ctxt->spurs.addr()), 128);
|
||||
|
||||
vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() {
|
||||
auto spurs = ctxt->spurs.get_priv_ptr();
|
||||
auto spurs = ctxt->spurs.priv_ptr();
|
||||
|
||||
// Halt if already initialised
|
||||
if (spurs->m.sysSrvOnSpu & (1 << ctxt->spuNum)) {
|
||||
|
@ -786,7 +786,7 @@ void spursSysServiceProcessRequests(SPUThread & spu, SpursKernelContext * ctxt)
|
|||
bool terminate = false;
|
||||
|
||||
vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() {
|
||||
auto spurs = ctxt->spurs.get_priv_ptr();
|
||||
auto spurs = ctxt->spurs.priv_ptr();
|
||||
|
||||
// Terminate request
|
||||
if (spurs->m.sysSrvMsgTerminate & (1 << ctxt->spuNum)) {
|
||||
|
@ -853,7 +853,7 @@ void spursSysServiceActivateWorkload(SPUThread & spu, SpursKernelContext * ctxt)
|
|||
}
|
||||
|
||||
vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() {
|
||||
auto spurs = ctxt->spurs.get_priv_ptr();
|
||||
auto spurs = ctxt->spurs.priv_ptr();
|
||||
|
||||
for (u32 i = 0; i < CELL_SPURS_MAX_WORKLOAD; i++) {
|
||||
// Update workload status and runnable flag based on the workload state
|
||||
|
@ -910,7 +910,7 @@ void spursSysServiceUpdateShutdownCompletionEvents(SPUThread & spu, SpursKernelC
|
|||
u32 wklNotifyBitSet;
|
||||
u8 spuPort;
|
||||
vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() {
|
||||
auto spurs = ctxt->spurs.get_priv_ptr();
|
||||
auto spurs = ctxt->spurs.priv_ptr();
|
||||
|
||||
wklNotifyBitSet = 0;
|
||||
spuPort = spurs->m.spuPort;;
|
||||
|
@ -952,7 +952,7 @@ void spursSysServiceTraceUpdate(SPUThread & spu, SpursKernelContext * ctxt, u32
|
|||
|
||||
u8 sysSrvMsgUpdateTrace;
|
||||
vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() {
|
||||
auto spurs = ctxt->spurs.get_priv_ptr();
|
||||
auto spurs = ctxt->spurs.priv_ptr();
|
||||
|
||||
sysSrvMsgUpdateTrace = spurs->m.sysSrvMsgUpdateTrace;
|
||||
spurs->m.sysSrvMsgUpdateTrace &= ~(1 << ctxt->spuNum);
|
||||
|
@ -1006,7 +1006,7 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte
|
|||
bool do_return = false;
|
||||
|
||||
vm::reservation_op(vm::cast(ctxt->spurs.addr() + offsetof(CellSpurs, m.wklState1)), 128, [&]() {
|
||||
auto spurs = ctxt->spurs.get_priv_ptr();
|
||||
auto spurs = ctxt->spurs.priv_ptr();
|
||||
|
||||
if (spurs->m.sysSrvWorkload[ctxt->spuNum] == 0xFF) {
|
||||
do_return = true;
|
||||
|
@ -1024,7 +1024,7 @@ void spursSysServiceCleanupAfterSystemWorkload(SPUThread & spu, SpursKernelConte
|
|||
spursSysServiceActivateWorkload(spu, ctxt);
|
||||
|
||||
vm::reservation_op(vm::cast(ctxt->spurs.addr()), 128, [&]() {
|
||||
auto spurs = ctxt->spurs.get_priv_ptr();
|
||||
auto spurs = ctxt->spurs.priv_ptr();
|
||||
|
||||
if (wklId >= CELL_SPURS_MAX_WORKLOAD) {
|
||||
spurs->m.wklCurrentContention[wklId & 0x0F] -= 0x10;
|
||||
|
@ -1158,7 +1158,7 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 *
|
|||
s32 rc = CELL_OK;
|
||||
s32 numNewlyReadyTasks;
|
||||
vm::reservation_op(vm::cast(ctxt->taskset.addr()), 128, [&]() {
|
||||
auto taskset = ctxt->taskset.get_priv_ptr();
|
||||
auto taskset = ctxt->taskset.priv_ptr();
|
||||
|
||||
// Verify taskset state is valid
|
||||
auto _0 = be_t<u128>::make(u128::from32(0));
|
||||
|
@ -1299,7 +1299,7 @@ s32 spursTasksetProcessRequest(SPUThread & spu, s32 request, u32 * taskId, u32 *
|
|||
|
||||
// Increment the ready count of the workload by the number of tasks that have become ready
|
||||
vm::reservation_op(vm::cast(kernelCtxt->spurs.addr()), 128, [&]() {
|
||||
auto spurs = kernelCtxt->spurs.get_priv_ptr();
|
||||
auto spurs = kernelCtxt->spurs.priv_ptr();
|
||||
|
||||
s32 readyCount = kernelCtxt->wklCurrentId < CELL_SPURS_MAX_WORKLOAD ? spurs->m.wklReadyCount1[kernelCtxt->wklCurrentId].read_relaxed() : spurs->m.wklIdleSpuCountOrReadyCount2[kernelCtxt->wklCurrentId & 0x0F].read_relaxed();
|
||||
readyCount += numNewlyReadyTasks;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -559,13 +559,12 @@ s32 _sys_printf(vm::ptr<const char> fmt) // va_args...
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _nid_E75C40F2(u32 dest)
|
||||
s32 sys_process_get_paramsfo(vm::ptr<char> buffer)
|
||||
{
|
||||
sysPrxForUser.Todo("Unnamed function 0xE75C40F2 (dest=0x%x) -> CELL_ENOENT", dest);
|
||||
sysPrxForUser.Warning("sys_process_get_paramsfo(buffer=0x%x)", buffer);
|
||||
|
||||
// prx: load some data (0x40 bytes) previously set by sys_process_get_paramsfo
|
||||
//memset(Memory + dest, 0, 0x40);
|
||||
return CELL_ENOENT;
|
||||
// prx: load some data (0x40 bytes) previously set by _sys_process_get_paramsfo syscall
|
||||
return _sys_process_get_paramsfo(buffer);
|
||||
}
|
||||
|
||||
Module sysPrxForUser("sysPrxForUser", []()
|
||||
|
@ -674,5 +673,5 @@ Module sysPrxForUser("sysPrxForUser", []()
|
|||
|
||||
REG_FUNC(sysPrxForUser, _sys_printf);
|
||||
|
||||
REG_UNNAMED(sysPrxForUser, E75C40F2);
|
||||
REG_FUNC(sysPrxForUser, sys_process_get_paramsfo);
|
||||
});
|
||||
|
|
33
rpcs3/Emu/SysCalls/Modules/sys_libc.cpp
Normal file
33
rpcs3/Emu/SysCalls/Modules/sys_libc.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "stdafx.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
#include "Emu/Cell/PPUInstrTable.h"
|
||||
|
||||
extern Module sys_libc;
|
||||
|
||||
namespace sys_libc_func
|
||||
{
|
||||
void memcpy(vm::ptr<void> dst, vm::ptr<const void> src, u32 size)
|
||||
{
|
||||
sys_libc.Warning("memcpy(dst=0x%x, src=0x%x, size=0x%x)", dst, src, size);
|
||||
|
||||
::memcpy(dst.get_ptr(), src.get_ptr(), size);
|
||||
}
|
||||
}
|
||||
|
||||
Module sys_libc("sys_libc", []()
|
||||
{
|
||||
using namespace PPU_instr;
|
||||
|
||||
REG_SUB(sys_libc, "", sys_libc_func, memcpy,
|
||||
se_op(CMPLDI(cr7, r5, 7)),
|
||||
se_op(CLRLDI(r3, r3, 32)),
|
||||
se_op(CLRLDI(r4, r4, 32)),
|
||||
se_op(MR(r11, r3)),
|
||||
se_op(BGT(cr7, XXX & 0xff)),
|
||||
se_op(CMPDI(r5, 0)),
|
||||
se_opt_op(MR(r9, r3)),
|
||||
{ SPET_MASKED_OPCODE, 0x4d820020, 0xffffffff },
|
||||
);
|
||||
});
|
|
@ -80,7 +80,7 @@ const ppu_func_caller sc_table[1024] =
|
|||
null_func,//bind_func(), //27 (0x01B) DBG
|
||||
null_func,//bind_func(_sys_process_get_number_of_object)//28 (0x01C) ROOT
|
||||
bind_func(sys_process_get_id), //29 (0x01D) ROOT
|
||||
bind_func(sys_process_get_paramsfo), //30 (0x01E)
|
||||
bind_func(_sys_process_get_paramsfo), //30 (0x01E)
|
||||
null_func,//bind_func(sys_process_get_ppu_guid), //31 (0x01F)
|
||||
|
||||
null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, //32-40 UNS
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "Emu/System.h"
|
||||
#include "Emu/SysCalls/SysCalls.h"
|
||||
|
||||
#include "Emu/FS/vfsFile.h"
|
||||
#include "Loader/PSF.h"
|
||||
#include "sys_memory.h"
|
||||
#include "sys_process.h"
|
||||
|
||||
|
@ -286,29 +288,25 @@ s32 sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags)
|
|||
return process_is_spu_lock_line_reservation_address(addr, flags);
|
||||
}
|
||||
|
||||
s32 sys_process_get_paramsfo(vm::ptr<u8> buffer)
|
||||
s32 _sys_process_get_paramsfo(vm::ptr<char> buffer)
|
||||
{
|
||||
sys_process.Todo("sys_process_get_paramsfo(buffer_addr=0x%x) -> CELL_ENOENT", buffer.addr());
|
||||
return CELL_ENOENT;
|
||||
sys_process.Warning("_sys_process_get_paramsfo(buffer=0x%x)", buffer);
|
||||
|
||||
/*//Before uncommenting this code, we should check if it is actually working.
|
||||
MemoryAllocator<be_t<u32>> fd;
|
||||
char filePath [] = "/app_home/../PARAM.SFO";
|
||||
if (!cellFsOpen(Memory.RealToVirtualAddr(filePath), 0, fd, NULL, 0))
|
||||
if (!Emu.GetTitleID().length())
|
||||
{
|
||||
return CELL_ENOENT;
|
||||
}
|
||||
|
||||
MemoryAllocator<be_t<u64>> pos, nread;
|
||||
cellFsLseek(fd, 0, CELL_SEEK_SET, pos); //TODO: Move to the appropriate offset (probably 0x3F7)
|
||||
cellFsRead(fd, buffer.addr(), 40, nread); //WARNING: If offset==0x3F7: The file will end before the buffer (40 bytes) is filled!
|
||||
cellFsClose(fd);
|
||||
memset(buffer.get_ptr(), 0, 0x40);
|
||||
memcpy(buffer.get_ptr() + 1, Emu.GetTitleID().c_str(), std::min<size_t>(Emu.GetTitleID().length(), 9));
|
||||
|
||||
return CELL_OK;*/
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 process_get_sdk_version(u32 pid, s32& ver)
|
||||
{
|
||||
// TODO: get correct SDK version for selected pid
|
||||
ver = Emu.m_sdk_version;
|
||||
// get correct SDK version for selected pid
|
||||
ver = Emu.GetSDKVersion();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ s32 sys_process_getpid();
|
|||
s32 sys_process_getppid();
|
||||
s32 sys_process_get_number_of_object(u32 object, vm::ptr<u32> nump);
|
||||
s32 sys_process_get_id(u32 object, vm::ptr<u32> buffer, u32 size, vm::ptr<u32> set_size);
|
||||
s32 sys_process_get_paramsfo(vm::ptr<u8> buffer);
|
||||
s32 _sys_process_get_paramsfo(vm::ptr<char> buffer);
|
||||
s32 sys_process_get_sdk_version(u32 pid, vm::ptr<s32> version);
|
||||
s32 sys_process_get_status(u64 unk);
|
||||
s32 sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags);
|
||||
|
|
|
@ -38,11 +38,6 @@ static const std::string& BreakPointsDBName = "BreakPoints.dat";
|
|||
static const u16 bpdb_version = 0x1000;
|
||||
extern std::atomic<u32> g_thread_count;
|
||||
|
||||
ModuleInitializer::ModuleInitializer()
|
||||
{
|
||||
Emu.AddModuleInit(std::move(std::unique_ptr<ModuleInitializer>(this)));
|
||||
}
|
||||
|
||||
Emulator::Emulator()
|
||||
: m_status(Stopped)
|
||||
, m_mode(DisAsm)
|
||||
|
@ -82,11 +77,6 @@ Emulator::~Emulator()
|
|||
|
||||
void Emulator::Init()
|
||||
{
|
||||
while(m_modules_init.size())
|
||||
{
|
||||
m_modules_init[0]->Init();
|
||||
m_modules_init.erase(m_modules_init.begin());
|
||||
}
|
||||
}
|
||||
|
||||
void Emulator::SetPath(const std::string& path, const std::string& elf_path)
|
||||
|
@ -265,24 +255,7 @@ void Emulator::Load()
|
|||
vm::close();
|
||||
return;
|
||||
}
|
||||
|
||||
// trying to load some info from PARAM.SFO
|
||||
vfsFile f2("/app_home/../PARAM.SFO");
|
||||
if (f2.IsOpened())
|
||||
{
|
||||
PSFLoader psf(f2);
|
||||
if (psf.Load(false))
|
||||
{
|
||||
std::string version = psf.GetString("PS3_SYSTEM_VER");
|
||||
|
||||
const size_t dot = version.find('.');
|
||||
if (dot != std::string::npos)
|
||||
{
|
||||
Emu.m_sdk_version = (std::stoi(version, nullptr, 16) << 20) | ((std::stoi(version.substr(dot + 1), nullptr, 16) & 0xffff) << 4) | 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LoadPoints(BreakPointsDBName);
|
||||
|
||||
m_status = Ready;
|
||||
|
|
|
@ -61,14 +61,6 @@ public:
|
|||
u32 GetTLSMemsz() const { return tls_memsz; }
|
||||
};
|
||||
|
||||
class ModuleInitializer
|
||||
{
|
||||
public:
|
||||
ModuleInitializer();
|
||||
|
||||
virtual void Init() = 0;
|
||||
};
|
||||
|
||||
class Emulator
|
||||
{
|
||||
enum Mode
|
||||
|
@ -83,7 +75,6 @@ class Emulator
|
|||
|
||||
u32 m_rsx_callback;
|
||||
u32 m_cpu_thr_stop;
|
||||
std::vector<std::unique_ptr<ModuleInitializer>> m_modules_init;
|
||||
|
||||
std::vector<u64> m_break_points;
|
||||
std::vector<u64> m_marked_points;
|
||||
|
@ -112,7 +103,6 @@ public:
|
|||
std::string m_emu_path;
|
||||
std::string m_title_id;
|
||||
std::string m_title;
|
||||
s32 m_sdk_version;
|
||||
|
||||
Emulator();
|
||||
~Emulator();
|
||||
|
@ -132,12 +122,12 @@ public:
|
|||
return m_emu_path;
|
||||
}
|
||||
|
||||
std::string GetTitleID() const
|
||||
const std::string& GetTitleID() const
|
||||
{
|
||||
return m_title_id;
|
||||
}
|
||||
|
||||
std::string GetTitle() const
|
||||
const std::string& GetTitle() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
@ -164,11 +154,6 @@ public:
|
|||
ModuleManager& GetModuleManager() { return *m_module_manager; }
|
||||
SyncPrimManager& GetSyncPrimManager() { return *m_sync_prim_manager; }
|
||||
|
||||
void AddModuleInit(std::unique_ptr<ModuleInitializer> m)
|
||||
{
|
||||
m_modules_init.push_back(std::move(m));
|
||||
}
|
||||
|
||||
void SetTLSData(u32 addr, u32 filesz, u32 memsz)
|
||||
{
|
||||
m_info.SetTLSData(addr, filesz, memsz);
|
||||
|
@ -191,6 +176,7 @@ public:
|
|||
u32 GetTLSMemsz() const { return m_info.GetTLSMemsz(); }
|
||||
|
||||
u32 GetMallocPageSize() { return m_info.GetProcParam().malloc_pagesize; }
|
||||
u32 GetSDKVersion() { return m_info.GetProcParam().sdk_version; }
|
||||
|
||||
u32 GetRSXCallback() const { return m_rsx_callback; }
|
||||
u32 GetCPUThreadStop() const { return m_cpu_thr_stop; }
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#include "stdafx_gui.h"
|
||||
#include "Utilities/rMsgBox.h"
|
||||
|
||||
#include "Emu/Cell/PPUProgramCompiler.h"
|
||||
using namespace PPU_opcodes;
|
||||
//#include "Emu/Cell/PPUProgramCompiler.h"
|
||||
//using namespace PPU_opcodes;
|
||||
|
||||
#include "CompilerELF.h"
|
||||
|
||||
enum CompilerIDs
|
||||
|
@ -392,8 +393,8 @@ void CompilerELF::LoadElf(wxCommandEvent& event)
|
|||
LoadElf(fmt::ToUTF8(ctrl.GetPath()));
|
||||
}
|
||||
|
||||
#include "Emu/Cell/PPUDisAsm.h"
|
||||
#include "Emu/Cell/PPUDecoder.h"
|
||||
//#include "Emu/Cell/PPUDisAsm.h"
|
||||
//#include "Emu/Cell/PPUDecoder.h"
|
||||
|
||||
void CompilerELF::LoadElf(const std::string& path)
|
||||
{
|
||||
|
|
|
@ -29,20 +29,22 @@ struct wxWriter : Log::LogListener
|
|||
wxTextAttr m_color_white;
|
||||
wxTextAttr m_color_yellow;
|
||||
wxTextAttr m_color_red;
|
||||
wxTextAttr m_color_green;
|
||||
MTRingbuffer<char, BUFFER_MAX_SIZE> messages;
|
||||
std::atomic<bool> newLog;
|
||||
bool inited;
|
||||
|
||||
wxWriter(wxTextCtrl* p_log, wxTextCtrl* p_tty) :
|
||||
m_color_white(wxColour(255, 255, 255)) ,
|
||||
m_color_yellow(wxColour(255, 255, 0)) ,
|
||||
m_color_red(wxColour(255, 0, 0)) ,
|
||||
m_log(p_log),
|
||||
m_tty(p_tty),
|
||||
newLog(false),
|
||||
inited(false)
|
||||
wxWriter(wxTextCtrl* p_log, wxTextCtrl* p_tty)
|
||||
: m_color_white(wxColour(255, 255, 255))
|
||||
, m_color_yellow(wxColour(255, 255, 0))
|
||||
, m_color_red(wxColour(255, 0, 0))
|
||||
, m_color_green(wxColour(0, 255, 0))
|
||||
, m_log(p_log)
|
||||
, m_tty(p_tty)
|
||||
, newLog(false)
|
||||
, inited(false)
|
||||
{
|
||||
m_log->Bind(EVT_LOG_COMMAND, [this](wxCommandEvent &evt){this->write(evt);});
|
||||
m_log->Bind(EVT_LOG_COMMAND, [this](wxCommandEvent &evt){ this->write(evt); });
|
||||
}
|
||||
|
||||
wxWriter(wxWriter &other) = delete;
|
||||
|
@ -83,6 +85,9 @@ struct wxWriter : Log::LogListener
|
|||
case Log::Error:
|
||||
llogcon->SetDefaultStyle(m_color_red);
|
||||
break;
|
||||
case Log::Success:
|
||||
llogcon->SetDefaultStyle(m_color_green);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "Debugger.h"
|
||||
#include "InterpreterDisAsm.h"
|
||||
#include "Emu/CPU/CPUThreadManager.h"
|
||||
#include "Emu/Cell/PPCThread.h"
|
||||
#include "Emu/CPU/CPUThread.h"
|
||||
|
||||
|
||||
class DbgEmuPanel : public wxPanel
|
||||
|
@ -95,7 +95,7 @@ public:
|
|||
break;
|
||||
|
||||
case DID_EXIT_THR_SYSCALL:
|
||||
Emu.GetCPU().RemoveThread(((PPCThread*)event.GetClientData())->GetId());
|
||||
Emu.GetCPU().RemoveThread(((CPUThread*)event.GetClientData())->GetId());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ void GLGSFrame::Flip(void* context)
|
|||
canvas->SwapBuffers();
|
||||
m_frames++;
|
||||
|
||||
const std::string sub_title = Emu.GetTitle() += Emu.GetTitleID().length() ? " [" + Emu.GetTitleID() + "] | " : " | ";
|
||||
const std::string sub_title = Emu.GetTitle() + (Emu.GetTitleID().length() ? " [" + Emu.GetTitleID() + "] | " : " | ");
|
||||
|
||||
if (fps_t.GetElapsedTimeInSec() >= 0.5)
|
||||
{
|
||||
|
|
|
@ -487,8 +487,8 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
|||
cbox_camera_type->Append("USB Video Class 1.1");
|
||||
|
||||
cbox_hle_loglvl->Append("All");
|
||||
cbox_hle_loglvl->Append("Success");
|
||||
cbox_hle_loglvl->Append("Warnings");
|
||||
cbox_hle_loglvl->Append("Success");
|
||||
cbox_hle_loglvl->Append("Errors");
|
||||
cbox_hle_loglvl->Append("Nothing");
|
||||
|
||||
|
|
|
@ -307,8 +307,6 @@ namespace loader
|
|||
return load_sprx(info);
|
||||
}
|
||||
|
||||
Emu.m_sdk_version = -1;
|
||||
|
||||
//store elf to memory
|
||||
vm::ps3::init();
|
||||
|
||||
|
@ -467,14 +465,10 @@ namespace loader
|
|||
LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr);
|
||||
}
|
||||
|
||||
if (!vm::check_addr(addr, 4))
|
||||
if (!patch_ppu_import(addr, index))
|
||||
{
|
||||
LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::write32(addr, HACK(index | EIF_SAVE_RTOC | EIF_PERFORM_BLR));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -576,7 +570,7 @@ namespace loader
|
|||
{
|
||||
m_stream->Seek(handler::get_stream_offset() + phdr.p_offset);
|
||||
m_stream->Read(phdr.p_vaddr.get_ptr(), phdr.p_filesz);
|
||||
hook_ppu_funcs((u32*)phdr.p_vaddr.get_ptr(), vm::cast(phdr.p_filesz));
|
||||
hook_ppu_funcs(vm::ptr<u32>::make(phdr.p_vaddr.addr()), vm::cast(phdr.p_filesz) / 4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -618,7 +612,6 @@ namespace loader
|
|||
*/
|
||||
|
||||
info = proc_param.info;
|
||||
Emu.m_sdk_version = info.sdk_version;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -689,7 +682,10 @@ namespace loader
|
|||
LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", is_lle ? "LLE " : "", SysCalls::GetHLEFuncName(nid), module_name, addr);
|
||||
}
|
||||
|
||||
vm::write32(addr, HACK(index | EIF_SAVE_RTOC | EIF_PERFORM_BLR));
|
||||
if (!patch_ppu_import(addr, index))
|
||||
{
|
||||
LOG_ERROR(LOADER, "Failed to inject code at address 0x%x", addr);
|
||||
}
|
||||
|
||||
//if (!func || !func->lle_func)
|
||||
//{
|
||||
|
|
|
@ -131,7 +131,6 @@
|
|||
<ClCompile Include="Emu\Audio\XAudio2\XAudio2Thread.cpp" />
|
||||
<ClCompile Include="Emu\Cell\MFC.cpp" />
|
||||
<ClCompile Include="Emu\Cell\PPCDecoder.cpp" />
|
||||
<ClCompile Include="Emu\Cell\PPCThread.cpp" />
|
||||
<ClCompile Include="Emu\Cell\PPULLVMRecompilerTests.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - MemLeak|x64'">true</ExcludedFromBuild>
|
||||
|
@ -279,6 +278,7 @@
|
|||
<ClCompile Include="Emu\SysCalls\Modules\sysPrxForUser.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\sys_http.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\sys_io.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\sys_libc.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\sys_net.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\SyncPrimitivesManager.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\SysCalls.cpp" />
|
||||
|
@ -362,7 +362,6 @@
|
|||
<ClInclude Include="Emu\Cell\PPCDecoder.h" />
|
||||
<ClInclude Include="Emu\Cell\PPCDisAsm.h" />
|
||||
<ClInclude Include="Emu\Cell\PPCInstrTable.h" />
|
||||
<ClInclude Include="Emu\Cell\PPCThread.h" />
|
||||
<ClInclude Include="Emu\Cell\PPUDecoder.h" />
|
||||
<ClInclude Include="Emu\Cell\PPUDisAsm.h" />
|
||||
<ClInclude Include="Emu\Cell\PPUInstrTable.h" />
|
||||
|
|
|
@ -341,9 +341,6 @@
|
|||
<ClCompile Include="Emu\Cell\PPCDecoder.cpp">
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\PPCThread.cpp">
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\PPUThread.cpp">
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
|
@ -860,6 +857,9 @@
|
|||
<ClCompile Include="Emu\RSX\CgBinaryVertexProgram.cpp">
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\Modules\sys_libc.cpp">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Crypto\aes.h">
|
||||
|
@ -1105,9 +1105,6 @@
|
|||
<ClInclude Include="Emu\Cell\PPCInstrTable.h">
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPCThread.h">
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPUDecoder.h">
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
|
|
Loading…
Add table
Reference in a new issue