Merge pull request #971 from Nekotekina/master

Optimization and some restrictions for ppu/armv7 function prototypes
This commit is contained in:
B1ackDaemon 2015-01-20 01:58:07 +02:00
commit 6a2eefaf3f
44 changed files with 1094 additions and 819 deletions

View File

@ -758,86 +758,86 @@ template<typename T, typename T1, T1 value> struct _se<be_t<T>, T1, value> : pub
#define se32(x) _se<u32, decltype(x), x>::value
#define se64(x) _se<u64, decltype(x), x>::value
template<typename T> __forceinline static u8 Read8(T& f)
template<typename T> __forceinline u8 Read8(T& f)
{
u8 ret;
f.Read(&ret, sizeof(ret));
return ret;
}
template<typename T> __forceinline static u16 Read16(T& f)
template<typename T> __forceinline u16 Read16(T& f)
{
be_t<u16> ret;
f.Read(&ret, sizeof(ret));
return ret;
}
template<typename T> __forceinline static u32 Read32(T& f)
template<typename T> __forceinline u32 Read32(T& f)
{
be_t<u32> ret;
f.Read(&ret, sizeof(ret));
return ret;
}
template<typename T> __forceinline static u64 Read64(T& f)
template<typename T> __forceinline u64 Read64(T& f)
{
be_t<u64> ret;
f.Read(&ret, sizeof(ret));
return ret;
}
template<typename T> __forceinline static u16 Read16LE(T& f)
template<typename T> __forceinline u16 Read16LE(T& f)
{
u16 ret;
f.Read(&ret, sizeof(ret));
return ret;
}
template<typename T> __forceinline static u32 Read32LE(T& f)
template<typename T> __forceinline u32 Read32LE(T& f)
{
u32 ret;
f.Read(&ret, sizeof(ret));
return ret;
}
template<typename T> __forceinline static u64 Read64LE(T& f)
template<typename T> __forceinline u64 Read64LE(T& f)
{
u64 ret;
f.Read(&ret, sizeof(ret));
return ret;
}
template<typename T> __forceinline static void Write8(T& f, const u8 data)
template<typename T> __forceinline void Write8(T& f, const u8 data)
{
f.Write(&data, sizeof(data));
}
template<typename T> __forceinline static void Write16LE(T& f, const u16 data)
template<typename T> __forceinline void Write16LE(T& f, const u16 data)
{
f.Write(&data, sizeof(data));
}
template<typename T> __forceinline static void Write32LE(T& f, const u32 data)
template<typename T> __forceinline void Write32LE(T& f, const u32 data)
{
f.Write(&data, sizeof(data));
}
template<typename T> __forceinline static void Write64LE(T& f, const u64 data)
template<typename T> __forceinline void Write64LE(T& f, const u64 data)
{
f.Write(&data, sizeof(data));
}
template<typename T> __forceinline static void Write16(T& f, const u16 data)
template<typename T> __forceinline void Write16(T& f, const u16 data)
{
Write16LE(f, re16(data));
}
template<typename T> __forceinline static void Write32(T& f, const u32 data)
template<typename T> __forceinline void Write32(T& f, const u32 data)
{
Write32LE(f, re32(data));
}
template<typename T> __forceinline static void Write64(T& f, const u64 data)
template<typename T> __forceinline void Write64(T& f, const u64 data)
{
Write64LE(f, re64(data));
}

View File

@ -235,3 +235,17 @@ LogChannel &LogManager::getChannel(LogType type)
{
return mChannels[static_cast<u32>(type)];
}
void log_message(Log::LogType type, Log::LogSeverity sev, const char* text)
{
log_message(type, sev, std::string(text));
}
void log_message(Log::LogType type, Log::LogSeverity sev, std::string text)
{
//another msvc bug makes this not work, uncomment this and delete everything else in this function when it's fixed
//Log::LogManager::getInstance().log({logType, severity, text})
Log::LogMessage msg{ type, sev, std::move(text) };
Log::LogManager::getInstance().log(msg);
}

View File

@ -126,24 +126,11 @@ static struct { inline operator Log::LogType() { return Log::LogType::SPU; } } S
static struct { inline operator Log::LogType() { return Log::LogType::ARMv7; } } ARMv7;
static struct { inline operator Log::LogType() { return Log::LogType::TTY; } } TTY;
inline void log_message(Log::LogType type, Log::LogSeverity sev, const char* text)
{
//another msvc bug makes this not work, uncomment this and delete everything else in this function when it's fixed
//Log::LogManager::getInstance().log({logType, severity, text})
void log_message(Log::LogType type, Log::LogSeverity sev, const char* text);
void log_message(Log::LogType type, Log::LogSeverity sev, std::string text);
Log::LogMessage msg{ type, sev, text };
Log::LogManager::getInstance().log(msg);
}
inline void log_message(Log::LogType type, Log::LogSeverity sev, const std::string& text)
template<typename... Targs>
__noinline void log_message(Log::LogType type, Log::LogSeverity sev, const char* fmt, Targs... args)
{
Log::LogMessage msg{ type, sev, text };
Log::LogManager::getInstance().log(msg);
}
template<typename T, typename... Ts>
inline void log_message(Log::LogType type, Log::LogSeverity sev, const char* text, T arg, Ts... args)
{
Log::LogMessage msg{ type, sev, fmt::format(text, arg, args...) };
Log::LogManager::getInstance().log(msg);
log_message(type, sev, fmt::detail::format(fmt, strlen(fmt), fmt::do_unveil(args)...));
}

View File

@ -3,7 +3,7 @@
std::string u128::to_hex() const
{
return fmt::Format("%016llx%016llx", _u64[1], _u64[0]);
return fmt::format("%016llx%016llx", _u64[1], _u64[0]);
}
std::string u128::to_xyzw() const
@ -11,6 +11,150 @@ std::string u128::to_xyzw() const
return fmt::Format("x: %g y: %g z: %g w: %g", _f[3], _f[2], _f[1], _f[0]);
}
std::string fmt::to_hex(u64 value, size_t count)
{
assert(count - 1 < 16);
count = std::max<u64>(count, 16 - cntlz64(value) / 4);
char res[16] = {};
for (size_t i = count - 1; ~i; i--, value /= 16)
{
res[i] = "0123456789abcdef"[value % 16];
}
return std::string(res, count);
}
std::string fmt::to_udec(u64 value)
{
char res[20] = {};
size_t first = sizeof(res);
if (!value)
{
res[--first] = '0';
}
for (; value; value /= 10)
{
res[--first] = '0' + (value % 10);
}
return std::string(&res[first], sizeof(res) - first);
}
std::string fmt::to_sdec(s64 svalue)
{
const bool sign = svalue < 0;
u64 value = sign ? -svalue : svalue;
char res[20] = {};
size_t first = sizeof(res);
if (!value)
{
res[--first] = '0';
}
for (; value; value /= 10)
{
res[--first] = '0' + (value % 10);
}
if (sign)
{
res[--first] = '-';
}
return std::string(&res[first], sizeof(res) - first);
}
size_t fmt::detail::get_fmt_start(const char* fmt, size_t len)
{
for (size_t i = 0; i < len; i++)
{
if (fmt[i] == '%')
{
return i;
}
}
return len;
}
size_t fmt::detail::get_fmt_len(const char* fmt, size_t len)
{
assert(len >= 2 && fmt[0] == '%');
size_t res = 2;
if (fmt[1] == '.' || fmt[1] == '0')
{
assert(len >= 4 && fmt[2] - '1' < 9);
res += 2;
fmt += 2;
len -= 2;
if (fmt[1] == '1')
{
assert(len >= 3 && fmt[2] - '0' < 7);
res++;
fmt++;
len--;
}
}
if (fmt[1] == 'l')
{
assert(len >= 3);
res++;
fmt++;
len--;
}
if (fmt[1] == 'l')
{
assert(len >= 3);
res++;
fmt++;
len--;
}
return res;
}
size_t fmt::detail::get_fmt_precision(const char* fmt, size_t len)
{
assert(len >= 2);
if (fmt[1] == '.' || fmt[1] == '0')
{
assert(len >= 4 && fmt[2] - '1' < 9);
if (fmt[2] == '1')
{
assert(len >= 5 && fmt[3] - '0' < 7);
return 10 + fmt[3] - '0';
}
return fmt[2] - '0';
}
return 1;
}
std::string fmt::detail::format(const char* fmt, size_t len)
{
const size_t fmt_start = get_fmt_start(fmt, len);
if (fmt_start != len)
{
throw "Excessive formatting: " + std::string(fmt, len);
}
return std::string(fmt, len);
}
extern const std::string fmt::placeholder = "???";
std::string replace_first(const std::string& src, const std::string& from, const std::string& to)

View File

@ -173,116 +173,20 @@ namespace fmt
return src;
}
std::string to_hex(u64 value, size_t count = 1);
std::string to_udec(u64 value);
std::string to_sdec(s64 value);
namespace detail
{
static std::string to_hex(u64 value, size_t count = 1)
{
assert(count - 1 < 16);
count = std::max<u64>(count, 16 - cntlz64(value) / 4);
size_t get_fmt_start(const char* fmt, size_t len);
size_t get_fmt_len(const char* fmt, size_t len);
size_t get_fmt_precision(const char* fmt, size_t len);
char res[16] = {};
for (size_t i = count - 1; ~i; i--, value /= 16)
{
res[i] = "0123456789abcdef"[value % 16];
}
return std::string(res, count);
}
static size_t get_fmt_start(const char* fmt, size_t len)
{
for (size_t i = 0; i < len; i++)
{
if (fmt[i] == '%')
{
return i;
}
}
return len;
}
static size_t get_fmt_len(const char* fmt, size_t len)
{
assert(len >= 2 && fmt[0] == '%');
size_t res = 2;
if (fmt[1] == '.' || fmt[1] == '0')
{
assert(len >= 4 && fmt[2] - '1' < 9);
res += 2;
fmt += 2;
len -= 2;
if (fmt[1] == '1')
{
assert(len >= 3 && fmt[2] - '0' < 7);
res++;
fmt++;
len--;
}
}
if (fmt[1] == 'l')
{
assert(len >= 3);
res++;
fmt++;
len--;
}
if (fmt[1] == 'l')
{
assert(len >= 3);
res++;
fmt++;
len--;
}
return res;
}
static size_t get_fmt_precision(const char* fmt, size_t len)
{
assert(len >= 2);
if (fmt[1] == '.' || fmt[1] == '0')
{
assert(len >= 4 && fmt[2] - '1' < 9);
if (fmt[2] == '1')
{
assert(len >= 5 && fmt[3] - '0' < 7);
return 10 + fmt[3] - '0';
}
return fmt[2] - '0';
}
return 1;
}
template<typename T, bool is_enum = std::is_enum<T>::value>
template<typename T>
struct get_fmt
{
static_assert(is_enum, "Unsupported fmt::format argument");
typedef typename std::underlying_type<T>::type underlying_type;
static std::string text(const char* fmt, size_t len, const T& arg)
{
return get_fmt<underlying_type>::text(fmt, len, (underlying_type)arg);
}
};
template<typename T, typename T2>
struct get_fmt<be_t<T, T2>, false>
{
static std::string text(const char* fmt, size_t len, const be_t<T, T2>& arg)
{
return get_fmt<T>::text(fmt, len, arg.value());
}
static_assert(!sizeof(T), "Unsupported fmt::format argument");
};
template<>
@ -296,7 +200,7 @@ namespace fmt
}
else if (fmt[len - 1] == 'd')
{
return std::to_string((u32)arg);
return to_udec(arg);
}
else
{
@ -318,7 +222,7 @@ namespace fmt
}
else if (fmt[len - 1] == 'd')
{
return std::to_string((u32)arg);
return to_udec(arg);
}
else
{
@ -340,7 +244,7 @@ namespace fmt
}
else if (fmt[len - 1] == 'd')
{
return std::to_string(arg);
return to_udec(arg);
}
else
{
@ -362,7 +266,7 @@ namespace fmt
}
else if (fmt[len - 1] == 'd')
{
return std::to_string(arg);
return to_udec(arg);
}
else
{
@ -384,7 +288,7 @@ namespace fmt
}
else if (fmt[len - 1] == 'd')
{
return std::to_string((s32)arg);
return to_sdec(arg);
}
else
{
@ -406,7 +310,7 @@ namespace fmt
}
else if (fmt[len - 1] == 'd')
{
return std::to_string((s32)arg);
return to_sdec(arg);
}
else
{
@ -428,7 +332,7 @@ namespace fmt
}
else if (fmt[len - 1] == 'd')
{
return std::to_string(arg);
return to_sdec(arg);
}
else
{
@ -450,7 +354,7 @@ namespace fmt
}
else if (fmt[len - 1] == 'd')
{
return std::to_string(arg);
return to_sdec(arg);
}
else
{
@ -621,16 +525,10 @@ namespace fmt
}
};
static std::string format(const char* fmt, size_t len)
{
const size_t fmt_start = get_fmt_start(fmt, len);
assert(fmt_start == len);
return std::string(fmt, len);
}
std::string format(const char* fmt, size_t len); // terminator
template<typename T, typename... Args>
static std::string format(const char* fmt, size_t len, const T& arg, Args... args)
std::string format(const char* fmt, size_t len, const T& arg, Args... args)
{
const size_t fmt_start = get_fmt_start(fmt, len);
const size_t fmt_len = get_fmt_len(fmt + fmt_start, len - fmt_start);
@ -640,8 +538,72 @@ namespace fmt
}
};
// formatting function with very limited functionality (compared to printf-like formatting) and be_t<> support
template<typename T, bool is_enum = std::is_enum<T>::value>
struct unveil
{
typedef T result_type;
__forceinline static result_type get_value(const T& arg)
{
return arg;
}
};
template<size_t N>
struct unveil<const char[N], false>
{
typedef const char* result_type;
__forceinline static result_type get_value(const char(&arg)[N])
{
return arg;
}
};
template<>
struct unveil<std::string, false>
{
typedef const std::string& result_type;
__forceinline static result_type get_value(const std::string& arg)
{
return arg;
}
};
template<typename T>
struct unveil<T, true>
{
typedef typename std::underlying_type<T>::type result_type;
__forceinline static result_type get_value(const T& arg)
{
return static_cast<result_type>(arg);
}
};
template<typename T, typename T2>
struct unveil<be_t<T, T2>, false>
{
typedef typename unveil<T>::result_type result_type;
__forceinline static result_type get_value(const be_t<T, T2>& arg)
{
return unveil<T>::get_value(arg.value());
}
};
template<typename T>
__forceinline typename unveil<T>::result_type do_unveil(const T& arg)
{
return unveil<T>::get_value(arg);
}
/*
fmt::format(const char* fmt, args...)
Formatting function with very limited functionality (compared to printf-like formatting) and be_t<> support
Supported types:
u8, s8 (%x, %d)
@ -652,29 +614,30 @@ namespace fmt
double (%x, %f)
bool (%x, %d, %s)
char*, const char*, std::string (%s)
be_t<> of any appropriate type in this list
enum of any appropriate type in this list
be_t<> of any appropriate type in this list (fmt::unveil)
enum of any appropriate type in this list (fmt::unveil)
External specializations (can be found in another headers):
vm::ps3::ptr (vm_ptr.h) (with appropriate address type, using .addr() can be avoided)
vm::ps3::bptr (vm_ptr.h)
vm::psv::ptr (vm_ptr.h)
vm::ps3::ref (vm_ref.h)
vm::ps3::bref (vm_ref.h)
vm::psv::ref (vm_ref.h)
vm::ps3::ptr (fmt::unveil) (vm_ptr.h) (with appropriate address type, using .addr() can be avoided)
vm::ps3::bptr (fmt::unveil) (vm_ptr.h)
vm::psv::ptr (fmt::unveil) (vm_ptr.h)
vm::ps3::ref (fmt::unveil) (vm_ref.h)
vm::ps3::bref (fmt::unveil) (vm_ref.h)
vm::psv::ref (fmt::unveil) (vm_ref.h)
Supported formatting:
%d - decimal; only basic std::to_string() functionality
%x - hexadecimal; %.8x - hexadecimal with the precision (from .2 to .16)
%d - decimal; to_sdec() and to_udec()
%x - hexadecimal; to_hex(), %08x - hexadecimal with minimal length (from 02 to 016)
%s - string; generates "true" or "false" for bool
%f - floating point; only basic std::to_string() functionality
Other features are not supported.
*/
template<typename... Args>
__forceinline static std::string format(const char* fmt, Args... args)
__forceinline std::string format(const char* fmt, Args... args)
{
return detail::format(fmt, strlen(fmt), args...);
return detail::format(fmt, strlen(fmt), do_unveil(args)...);
}
//convert a wxString to a std::string encoded in utf8

View File

@ -90,9 +90,9 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_
{
switch (const u8 prefix = *code)
{
case 0xf0: throw fmt::Format("decode_x64_reg_op(%.16llXh): 0x%.2X (LOCK prefix) found", code - decoded_size, prefix); // group 1
case 0xf2: throw fmt::Format("decode_x64_reg_op(%.16llXh): 0x%.2X (REPNE/REPNZ prefix) found", code - decoded_size, prefix); // group 1
case 0xf3: throw fmt::Format("decode_x64_reg_op(%.16llXh): 0x%.2X (REP/REPE/REPZ prefix) found", code - decoded_size, prefix); // group 1
case 0xf0: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (LOCK prefix) found", (size_t)code - decoded_size, prefix); // group 1
case 0xf2: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (REPNE/REPNZ prefix) found", (size_t)code - decoded_size, prefix); // group 1
case 0xf3: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (REP/REPE/REPZ prefix) found", (size_t)code - decoded_size, prefix); // group 1
case 0x2e: // group 2
case 0x36:
@ -108,12 +108,12 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_
}
else
{
throw fmt::Format("decode_x64_reg_op(%.16llXh): 0x%.2X (group 2 prefix) found after 0x%.2X", code - decoded_size, prefix, pg2);
throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (group 2 prefix) found after 0x%02x", (size_t)code - decoded_size, prefix, pg2);
}
}
case 0x66: throw fmt::Format("decode_x64_reg_op(%.16llXh): 0x%.2X (operand-size override prefix) found", code - decoded_size, prefix); // group 3
case 0x67: throw fmt::Format("decode_x64_reg_op(%.16llXh): 0x%.2X (address-size override prefix) found", code - decoded_size, prefix); // group 4
case 0x66: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (operand-size override prefix) found", (size_t)code - decoded_size, prefix); // group 3
case 0x67: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (address-size override prefix) found", (size_t)code - decoded_size, prefix); // group 4
default:
{
@ -121,11 +121,11 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_
{
if (rex)
{
throw fmt::Format("decode_x64_reg_op(%.16llXh): 0x%.2X (REX prefix) found after 0x%.2X", code - decoded_size, prefix, rex);
throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (REX prefix) found after 0x%02x", (size_t)code - decoded_size, prefix, rex);
}
if (prefix & 0x80) // check REX.W bit
{
throw fmt::Format("decode_x64_reg_op(%.16llXh): 0x%.2X (REX.W bit) found", code - decoded_size, prefix);
throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (REX.W bit) found", (size_t)code - decoded_size, prefix);
}
if (prefix & 0x04) // check REX.R bit
{
@ -185,88 +185,119 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_
}
default:
{
throw fmt::Format("decode_x64_reg_op(%.16llXh): unsupported opcode found (0x%.2X, 0x%.2X, 0x%.2X)", code - decoded_size, op1, code[0], code[1]);
throw fmt::format("decode_x64_reg_op(%016llxh): unsupported opcode found (0x%02x, 0x%02x, 0x%02x)", (size_t)code - decoded_size, op1, code[0], code[1]);
}
}
}
#ifdef _WIN32
typedef CONTEXT x64_context;
#define RIP 16
#define X64REG(context, reg) ((&context->Rax)[reg])
#else
typedef ucontext_t x64_context;
typedef decltype(REG_RIP) reg_table_t;
#define RIP 16
static const reg_table_t reg_table[17] =
{
REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI,
REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP
};
#define X64REG(context, reg) (context->uc_mcontext.gregs[reg_table[reg]])
#endif
bool handle_access_violation(const u32 addr, x64_context* context)
{
if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) // RawSPU MMIO registers
{
// one x64 instruction is manually decoded and interpreted
x64_op_t op;
x64_reg_t reg;
size_t size;
decode_x64_reg_op((const u8*)X64REG(context, RIP), op, reg, size);
// get x64 reg value (for store operations)
u64 reg_value;
if (reg - X64R32 < 16)
{
// load the value from x64 register
reg_value = (u32)X64REG(context, reg - X64R32);
}
else if (reg == X64_IMM32)
{
// load the immediate value (assuming it's at the end of the instruction)
reg_value = *(u32*)(X64REG(context, RIP) + size - 4);
}
else
{
assert(!"Invalid x64_reg_t value");
}
bool save_reg = false;
switch (op)
{
case X64OP_LOAD:
{
reg_value = re32(Memory.ReadMMIO32(addr));
save_reg = true;
break;
}
case X64OP_STORE:
{
Memory.WriteMMIO32(addr, re32((u32)reg_value));
break;
}
default: assert(!"Invalid x64_op_t value");
}
// save x64 reg value (for load operations)
if (save_reg)
{
if (reg - X64R32 < 16)
{
// store the value into x64 register
X64REG(context, reg - X64R32) = (u32)reg_value;
}
else
{
assert(!"Invalid x64_reg_t value (saving)");
}
}
// skip decoded instruction
X64REG(context, RIP) += size;
return true;
}
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
return false;
}
#ifdef _WIN32
void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
{
const u64 addr64 = (u64)pExp->ExceptionRecord->ExceptionInformation[1] - (u64)Memory.GetBaseAddr();
const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0;
if (u == EXCEPTION_ACCESS_VIOLATION && addr64 < 0x100000000ull)
if (u == EXCEPTION_ACCESS_VIOLATION && (u32)addr64 == addr64)
{
const u32 addr = (u32)addr64;
if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) // RawSPU MMIO registers
if (handle_access_violation((u32)addr64, pExp->ContextRecord))
{
// one x64 instruction is manually decoded and interpreted
x64_op_t op;
x64_reg_t reg;
size_t size;
decode_x64_reg_op((const u8*)pExp->ContextRecord->Rip, op, reg, size);
// get x64 reg value (for store operations)
u64 reg_value;
if (reg - X64R32 < 16)
{
// load the value from x64 register
reg_value = (u32)(&pExp->ContextRecord->Rax)[reg - X64R32];
}
else if (reg == X64_IMM32)
{
// load the immediate value (assuming it's at the end of the instruction)
reg_value = *(u32*)(pExp->ContextRecord->Rip + size - 4);
}
else
{
assert(!"Invalid x64_reg_t value");
}
bool save_reg = false;
switch (op)
{
case X64OP_LOAD:
{
assert(!is_writing);
reg_value = re32(Memory.ReadMMIO32(addr));
save_reg = true;
break;
}
case X64OP_STORE:
{
assert(is_writing);
Memory.WriteMMIO32(addr, re32((u32)reg_value));
break;
}
default: assert(!"Invalid x64_op_t value");
}
// save x64 reg value (for load operations)
if (save_reg)
{
if (reg - X64R32 < 16)
{
// store the value into x64 register
(&pExp->ContextRecord->Rax)[reg - X64R32] = (u32)reg_value;
}
else
{
assert(!"Invalid x64_reg_t value (saving)");
}
}
// skip decoded instruction
pExp->ContextRecord->Rip += size;
// restore context (further code shouldn't be reached)
RtlRestoreContext(pExp->ContextRecord, nullptr);
// it's dangerous because destructors won't be executed
}
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
throw fmt::Format("Access violation %s location 0x%x", is_writing ? "writing" : "reading", addr);
throw fmt::format("Access violation %s location 0x%llx", is_writing ? "writing" : "reading", addr64);
}
// else some fatal error (should crash)
@ -274,89 +305,18 @@ void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
#else
typedef decltype(REG_RIP) reg_table_t;
static const reg_table_t reg_table[16] =
{
REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI,
REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15
};
void signal_handler(int sig, siginfo_t* info, void* uct)
{
ucontext_t* const ctx = (ucontext_t*)uct;
const u64 addr64 = (u64)info->si_addr - (u64)Memory.GetBaseAddr();
//const bool is_writing = false; // TODO: get it correctly
if (addr64 < 0x100000000ull && GetCurrentNamedThread())
if ((u32)addr64 == addr64 && GetCurrentNamedThread())
{
const u32 addr = (u32)addr64;
if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) // RawSPU MMIO registers
if (handle_access_violation((u32)addr64, (ucontext_t*)uct))
{
// one x64 instruction is manually decoded and interpreted
x64_op_t op;
x64_reg_t reg;
size_t size;
decode_x64_reg_op((const u8*)ctx->uc_mcontext.gregs[REG_RIP], op, reg, size);
// get x64 reg value (for store operations)
u64 reg_value;
if (reg - X64R32 < 16)
{
// load the value from x64 register
reg_value = (u32)ctx->uc_mcontext.gregs[reg_table[reg - X64R32]];
}
else if (reg == X64_IMM32)
{
// load the immediate value (assuming it's at the end of the instruction)
reg_value = *(u32*)(ctx->uc_mcontext.gregs[REG_RIP] + size - 4);
}
else
{
assert(!"Invalid x64_reg_t value");
return; // proceed execution
}
bool save_reg = false;
switch (op)
{
case X64OP_LOAD:
{
//assert(!is_writing);
reg_value = re32(Memory.ReadMMIO32(addr));
save_reg = true;
break;
}
case X64OP_STORE:
{
//assert(is_writing);
Memory.WriteMMIO32(addr, re32((u32)reg_value));
break;
}
default: assert(!"Invalid x64_op_t value");
}
// save x64 reg value (for load operations)
if (save_reg)
{
if (reg - X64R32 < 16)
{
// store the value into x64 register
ctx->uc_mcontext.gregs[reg_table[reg - X64R32]] = (u32)reg_value;
}
else
{
assert(!"Invalid x64_reg_t value (saving)");
}
}
// skip decoded instruction
ctx->uc_mcontext.gregs[REG_RIP] += size;
return; // now execution should proceed
//setcontext(ctx);
}
// TODO: allow recovering from a page fault as a feature of PS3 virtual memory
throw fmt::Format("Access violation %s location 0x%x", /*is_writing ? "writing" : "reading"*/ "at", addr);
// TODO: this may be wrong
throw fmt::format("Access violation at location 0x%llx", addr64);
}
// else some fatal error
@ -394,7 +354,7 @@ void SetCurrentNamedThread(NamedThreadBase* value)
if (value && value->m_tls_assigned.exchange(true))
{
LOG_ERROR(GENERAL, "Thread '%s' was already assigned to g_tls_this_thread of another thread", value->GetThreadName().c_str());
LOG_ERROR(GENERAL, "Thread '%s' was already assigned to g_tls_this_thread of another thread", value->GetThreadName());
g_tls_this_thread = nullptr;
}
else

View File

@ -1,5 +1,4 @@
#pragma once
#include "Emu/CPU/CPUThread.h"
#include "Emu/Memory/Memory.h"
@ -210,3 +209,131 @@ public:
return *this;
}
};
template<typename T, bool is_enum = std::is_enum<T>::value>
struct cast_armv7_gpr
{
static_assert(is_enum, "Invalid type for cast_armv7_gpr");
typedef typename std::underlying_type<T>::type underlying_type;
__forceinline static u32 to_gpr(const T& value)
{
return cast_armv7_gpr<underlying_type>::to_gpr(static_cast<underlying_type>(value));
}
__forceinline static T from_gpr(const u32 reg)
{
return static_cast<T>(cast_armv7_gpr<underlying_type>::from_gpr(reg));
}
};
template<>
struct cast_armv7_gpr<u8, false>
{
__forceinline static u32 to_gpr(const u8& value)
{
return value;
}
__forceinline static u8 from_gpr(const u32 reg)
{
return static_cast<u8>(reg);
}
};
template<>
struct cast_armv7_gpr<u16, false>
{
__forceinline static u32 to_gpr(const u16& value)
{
return value;
}
__forceinline static u16 from_gpr(const u32 reg)
{
return static_cast<u16>(reg);
}
};
template<>
struct cast_armv7_gpr<u32, false>
{
__forceinline static u32 to_gpr(const u32& value)
{
return value;
}
__forceinline static u32 from_gpr(const u32 reg)
{
return reg;
}
};
template<>
struct cast_armv7_gpr<s8, false>
{
__forceinline static u32 to_gpr(const s8& value)
{
return value;
}
__forceinline static s8 from_gpr(const u32 reg)
{
return static_cast<s8>(reg);
}
};
template<>
struct cast_armv7_gpr<s16, false>
{
__forceinline static u32 to_gpr(const s16& value)
{
return value;
}
__forceinline static s16 from_gpr(const u32 reg)
{
return static_cast<s16>(reg);
}
};
template<>
struct cast_armv7_gpr<s32, false>
{
__forceinline static u32 to_gpr(const s32& value)
{
return value;
}
__forceinline static s32 from_gpr(const u32 reg)
{
return static_cast<s32>(reg);
}
};
template<>
struct cast_armv7_gpr<bool, false>
{
__forceinline static u32 to_gpr(const bool& value)
{
return value;
}
__forceinline static bool from_gpr(const u32 reg)
{
return reinterpret_cast<const bool&>(reg);
}
};
template<typename T>
__forceinline u32 cast_to_armv7_gpr(const T& value)
{
return cast_armv7_gpr<T>::to_gpr(value);
}
template<typename T>
__forceinline T cast_from_armv7_gpr(const u32 reg)
{
return cast_armv7_gpr<T>::from_gpr(reg);
}

View File

@ -95,20 +95,18 @@ s32 sceKernelCreateThread(
s32 cpuAffinityMask,
vm::psv::ptr<const SceKernelThreadOptParam> pOptParam)
{
sceLibKernel.Error("sceKernelCreateThread(pName=0x%x ('%s'), entry=0x%x, initPriority=%d, stackSize=0x%x, attr=0x%x, cpuAffinityMask=0x%x, pOptParam=0x%x)",
pName, pName.get_ptr(), entry, initPriority, stackSize, attr, cpuAffinityMask, pOptParam);
sceLibKernel.Error("sceKernelCreateThread(pName=0x%x, entry=0x%x, initPriority=%d, stackSize=0x%x, attr=0x%x, cpuAffinityMask=0x%x, pOptParam=0x%x)",
pName, entry, initPriority, stackSize, attr, cpuAffinityMask, pOptParam);
std::string name = pName.get_ptr();
ARMv7Thread& new_thread = *(ARMv7Thread*)&Emu.GetCPU().AddThread(CPU_THREAD_ARMv7);
ARMv7Thread& new_thread = static_cast<ARMv7Thread&>(Emu.GetCPU().AddThread(CPU_THREAD_ARMv7));
u32 id = new_thread.GetId();
new_thread.SetEntry(entry.addr() ^ 1);
new_thread.SetPrio(initPriority);
new_thread.SetStackSize(stackSize);
new_thread.SetName(name);
new_thread.SetName(pName.get_ptr());
sceLibKernel.Error("*** New ARMv7 Thread [%s] (entry_addr=0x%x): id = %d", name.c_str(), entry.addr(), id);
sceLibKernel.Error("*** New ARMv7 Thread [%s] (entry=0x%x)^1: id = %d", pName.get_ptr(), entry, id);
new_thread.Run();
@ -128,15 +126,17 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr<const void> pAr
RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID);
}
ARMv7Thread& thread = static_cast<ARMv7Thread&>(*t);
// push arg block onto the stack
u32 pos = (static_cast<ARMv7Thread*>(t.get())->SP -= argSize);
const u32 pos = (thread.SP -= argSize);
memcpy(vm::get_ptr<void>(pos), pArgBlock.get_ptr(), argSize);
// set SceKernelThreadEntry function arguments
static_cast<ARMv7Thread*>(t.get())->write_gpr(0, argSize);
static_cast<ARMv7Thread*>(t.get())->write_gpr(1, pos);
thread.write_gpr(0, argSize);
thread.write_gpr(1, pos);
t->Exec();
thread.Exec();
return SCE_OK;
}

View File

@ -425,7 +425,7 @@ namespace psv_func_detail
static __forceinline T func(ARMv7Thread& CPU)
{
return (T&)CPU.GPR[g_count - 1];
return cast_from_armv7_gpr<T>(CPU.GPR[g_count - 1]);
}
};
@ -444,7 +444,7 @@ namespace psv_func_detail
struct bind_arg<T, ARG_VECTOR, g_count, f_count, v_count>
{
static_assert(v_count <= 0, "TODO: Unsupported argument type (vector)");
static_assert(sizeof(T) == 16, "Invalid function argument type for ARG_VECTOR");
static_assert(std::is_same<T, u128>::value, "Invalid function argument type for ARG_VECTOR");
static __forceinline T func(ARMv7Thread& CPU)
{
@ -460,8 +460,9 @@ namespace psv_func_detail
static __forceinline T func(ARMv7Thread& CPU)
{
// TODO: check
const u32 res = CPU.GetStackArg(g_count);
return (T&)res;
return cast_from_armv7_gpr<T>(res);
}
};
@ -473,10 +474,9 @@ 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(ARMv7Thread& CPU, T result)
static __forceinline void func(ARMv7Thread& CPU, const T& result)
{
CPU.GPR[0] = 0; // TODO
(T&)CPU.GPR[0] = result;
CPU.GPR[0] = cast_to_armv7_gpr<T>(result);
}
};
@ -485,7 +485,7 @@ namespace psv_func_detail
//{
// static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT");
// static __forceinline void func(ARMv7Thread& CPU, T result)
// static __forceinline void func(ARMv7Thread& CPU, const T& result)
// {
// }
//};
@ -493,9 +493,9 @@ namespace psv_func_detail
//template<typename T>
//struct bind_result<T, ARG_VECTOR>
//{
// static_assert(sizeof(T) == 16, "Invalid function result type for ARG_VECTOR");
// static_assert(std::is_same<T, u128>::value, "Invalid function result type for ARG_VECTOR");
// static __forceinline void func(ARMv7Thread& CPU, const T result)
// static __forceinline void func(ARMv7Thread& CPU, const T& result)
// {
// }
//};
@ -519,21 +519,21 @@ namespace psv_func_detail
};
template <typename RT, typename F, typename Tuple>
static __forceinline RT call(F f, Tuple && t)
__forceinline RT call(F f, Tuple && t)
{
typedef typename std::decay<Tuple>::type ttype;
return psv_func_detail::call_impl<RT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
}
template<int g_count, int f_count, int v_count>
static __forceinline std::tuple<> iterate(ARMv7Thread& CPU)
__forceinline std::tuple<> iterate(ARMv7Thread& CPU)
{
// terminator
return std::tuple<>();
}
template<int g_count, int f_count, int v_count, typename T, typename... A>
static __forceinline std::tuple<T, A...> iterate(ARMv7Thread& CPU)
__forceinline std::tuple<T, A...> iterate(ARMv7Thread& CPU)
{
static_assert(!std::is_pointer<T>::value, "Invalid function argument type (pointer)");
static_assert(!std::is_reference<T>::value, "Invalid function argument type (reference)");
@ -550,6 +550,16 @@ namespace psv_func_detail
return std::tuple_cat(std::tuple<T>(bind_arg<T, t, g, f, v>::func(CPU)), iterate<g, f, v, A...>(CPU));
}
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... T>
class func_binder;
@ -606,13 +616,7 @@ namespace psv_func_detail
virtual void operator()(ARMv7Thread& CPU)
{
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
const bool is_float = std::is_floating_point<RT>::value;
const bool is_vector = std::is_same<RT, u128>::value;
const bind_arg_type t = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
bind_result<RT, t>::func(CPU, call<RT>(m_call, iterate<0, 0, 0, T...>(CPU)));
bind_result<RT, result_type<RT>::value>::func(CPU, call<RT>(m_call, iterate<0, 0, 0, T...>(CPU)));
}
};
@ -631,13 +635,7 @@ namespace psv_func_detail
virtual void operator()(ARMv7Thread& CPU)
{
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
const bool is_float = std::is_floating_point<RT>::value;
const bool is_vector = std::is_same<RT, u128>::value;
const bind_arg_type t = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
bind_result<RT, t>::func(CPU, call<RT>(m_call, std::tuple_cat(std::tuple<ARMv7Thread&>(CPU), iterate<0, 0, 0, T...>(CPU))));
bind_result<RT, result_type<RT>::value>::func(CPU, call<RT>(m_call, std::tuple_cat(std::tuple<ARMv7Thread&>(CPU), iterate<0, 0, 0, T...>(CPU))));
}
};
}

View File

@ -18,19 +18,19 @@ protected:
switch(m_mode)
{
case CPUDisAsm_DumpMode:
last_opcode = fmt::Format("\t%08x:\t%02x %02x %02x %02x\t%s\n", dump_pc,
last_opcode = fmt::format("\t%08x:\t%02x %02x %02x %02x\t%s\n", dump_pc,
offset[dump_pc],
offset[dump_pc + 1],
offset[dump_pc + 2],
offset[dump_pc + 3], value.c_str());
offset[dump_pc + 3], value);
break;
case CPUDisAsm_InterpreterMode:
last_opcode = fmt::Format("[%08x] %02x %02x %02x %02x: %s", dump_pc,
last_opcode = fmt::format("[%08x] %02x %02x %02x %02x: %s", dump_pc,
offset[dump_pc],
offset[dump_pc + 1],
offset[dump_pc + 2],
offset[dump_pc + 3], value.c_str());
offset[dump_pc + 3], value);
break;
case CPUDisAsm_CompilerElfMode:

View File

@ -70,12 +70,7 @@ public:
std::string GetName() const { return NamedThreadBase::GetThreadName(); }
std::string GetFName() const
{
return
fmt::Format("%s[%d] Thread%s",
GetTypeString().c_str(),
m_id,
(GetName().empty() ? std::string("") : fmt::Format(" (%s)", GetName().c_str())).c_str()
);
return fmt::format("%s[%d] Thread (%s)", GetTypeString(), m_id, GetName());
}
static std::string CPUThreadTypeToString(CPUThreadType type)
@ -111,8 +106,7 @@ public:
virtual std::string GetThreadName() const
{
std::string temp = (GetFName() + fmt::Format("[0x%08x]", PC));
return temp;
return fmt::format("%s[0x%08x]", GetFName(), PC);
}
CPUDecoder * GetDecoder() { return m_dec; };

View File

@ -55,7 +55,7 @@ CPUThread& CPUThreadManager::AddThread(CPUThreadType type)
default: assert(0);
}
new_thread->SetId(Emu.GetIdManager().GetNewID(fmt::Format("%s Thread", new_thread->GetTypeString().c_str()), new_thread));
new_thread->SetId(Emu.GetIdManager().GetNewID(new_thread->GetTypeString() + " Thread", new_thread));
m_threads.push_back(new_thread);
SendDbgCommand(DID_CREATE_THREAD, new_thread.get());

View File

@ -9,7 +9,7 @@ public:
virtual std::string GetThreadName() const
{
return (GetFName() + fmt::Format("[0x%08x]", PC));
return fmt::format("%s[0x%08x]", GetFName(), PC);
}
protected:

View File

@ -831,93 +831,158 @@ public:
ppu_thread& gpr(uint index, u64 value);
};
template<typename T, size_t size = sizeof(T)>
template<typename T, bool is_enum = std::is_enum<T>::value>
struct cast_ppu_gpr
{
static_assert(sizeof(T) <= 8, "Invalid type for cast_ppu_gpr");
static_assert(is_enum, "Invalid type for cast_ppu_gpr");
typedef typename std::underlying_type<T>::type underlying_type;
__forceinline static u64 to_gpr(const T& value)
{
u64 result = 0;
(T&)result = value;
return result;
return cast_ppu_gpr<underlying_type>::to_gpr(static_cast<underlying_type>(value));
}
};
template<typename T>
struct cast_ppu_gpr<T, 1>
__forceinline static T from_gpr(const u64 reg)
{
__forceinline static u64 to_gpr(const T& value)
{
return (u8&)value;
}
};
template<typename T>
struct cast_ppu_gpr<T, 2>
{
__forceinline static u64 to_gpr(const T& value)
{
return (u16&)value;
}
};
template<typename T>
struct cast_ppu_gpr<T, 4>
{
__forceinline static u64 to_gpr(const T& value)
{
return (u32&)value;
}
};
template<typename T>
struct cast_ppu_gpr<T, 8>
{
__forceinline static u64 to_gpr(const T& value)
{
return (u64&)value;
return static_cast<T>(cast_ppu_gpr<underlying_type>::from_gpr(reg));
}
};
template<>
struct cast_ppu_gpr<s8, 1>
struct cast_ppu_gpr<u8, false>
{
__forceinline static u64 to_gpr(const u8& value)
{
return value;
}
__forceinline static u8 from_gpr(const u64 reg)
{
return static_cast<u8>(reg);
}
};
template<>
struct cast_ppu_gpr<u16, false>
{
__forceinline static u64 to_gpr(const u16& value)
{
return value;
}
__forceinline static u16 from_gpr(const u64 reg)
{
return static_cast<u16>(reg);
}
};
template<>
struct cast_ppu_gpr<u32, false>
{
__forceinline static u64 to_gpr(const u32& value)
{
return value;
}
__forceinline static u32 from_gpr(const u64 reg)
{
return static_cast<u32>(reg);
}
};
template<>
struct cast_ppu_gpr<u64, false>
{
__forceinline static u64 to_gpr(const u64& value)
{
return value;
}
__forceinline static u64 from_gpr(const u64 reg)
{
return reg;
}
};
template<>
struct cast_ppu_gpr<s8, false>
{
__forceinline static u64 to_gpr(const s8& value)
{
return value;
}
__forceinline static s8 from_gpr(const u64 reg)
{
return static_cast<s8>(reg);
}
};
template<>
struct cast_ppu_gpr<s16, 2>
struct cast_ppu_gpr<s16, false>
{
__forceinline static u64 to_gpr(const s16& value)
{
return value;
}
__forceinline static s16 from_gpr(const u64 reg)
{
return static_cast<s16>(reg);
}
};
template<>
struct cast_ppu_gpr<s32, 4>
struct cast_ppu_gpr<s32, false>
{
__forceinline static u64 to_gpr(const s32& value)
{
return value;
}
__forceinline static s32 from_gpr(const u64 reg)
{
return static_cast<s32>(reg);
}
};
template<>
struct cast_ppu_gpr<s64, 8>
struct cast_ppu_gpr<s64, false>
{
__forceinline static u64 to_gpr(const s64& value)
{
return value;
}
__forceinline static s64 from_gpr(const u64 reg)
{
return static_cast<s64>(reg);
}
};
template<>
struct cast_ppu_gpr<bool, false>
{
__forceinline static u64 to_gpr(const bool& value)
{
return value;
}
__forceinline static bool from_gpr(const u64 reg)
{
return reinterpret_cast<const bool&>(reg);
}
};
template<typename T>
__forceinline static u64 cast_to_ppu_gpr(const T& value)
__forceinline u64 cast_to_ppu_gpr(const T& value)
{
return cast_ppu_gpr<T>::to_gpr(value);
}
template<typename T>
__forceinline T cast_from_ppu_gpr(const u64 reg)
{
return cast_ppu_gpr<T>::from_gpr(reg);
}

View File

@ -228,7 +228,7 @@ u8 SPURecompilerCore::DecodeMemory(const u32 address)
//need_check = true;
}
}
//LOG_ERROR(Log::SPU, "SPURecompilerCore::DecodeMemory(ls_addr=0x%x): code has changed", pos * sizeof(u32));
//LOG_ERROR(Log::SPU, "SPURecompilerCore::DecodeMemory(ls=0x%x): code has changed", pos * sizeof(u32));
}
}
@ -239,7 +239,7 @@ u8 SPURecompilerCore::DecodeMemory(const u32 address)
did_compile = true;
if (entry[pos].valid == 0)
{
LOG_ERROR(Log::SPU, "SPURecompilerCore::Compile(ls_addr=0x%x): branch to 0x0 opcode", pos * sizeof(u32));
LOG_ERROR(Log::SPU, "SPURecompilerCore::Compile(ls=0x%x): branch to 0x0 opcode", pos * sizeof(u32));
Emu.Pause();
return 0;
}
@ -255,7 +255,7 @@ u8 SPURecompilerCore::DecodeMemory(const u32 address)
//if (did_compile)
{
//LOG2_OPCODE("SPURecompilerCore::DecodeMemory(ls_addr=0x%x): NewPC = 0x%llx", address, (u64)res << 2);
//LOG2_OPCODE("SPURecompilerCore::DecodeMemory(ls=0x%x): NewPC = 0x%llx", address, (u64)res << 2);
//if (pos == 0x19c >> 2)
{
//Emu.Pause();
@ -281,7 +281,7 @@ u8 SPURecompilerCore::DecodeMemory(const u32 address)
if (did_compile)
{
//LOG2_OPCODE("SPURecompilerCore::DecodeMemory(ls_addr=0x%x): NewPC = 0x%llx", address, (u64)res << 2);
//LOG2_OPCODE("SPURecompilerCore::DecodeMemory(ls=0x%x): NewPC = 0x%llx", address, (u64)res << 2);
//if (pos == 0x340 >> 2)
{
//Emu.Pause();

View File

@ -83,21 +83,6 @@ public:
void UnregisterPages(u64 addr, u32 size);
u32 RealToVirtualAddr(const void* addr)
{
const u64 res = (u64)addr - (u64)GetBaseAddr();
if ((u32)res == res)
{
return (u32)res;
}
else
{
assert(!addr);
return 0;
}
}
u32 InitRawSPU(MemoryBlock* raw_spu);
void CloseRawSPU(MemoryBlock* raw_spu, const u32 num);

View File

@ -52,6 +52,20 @@ namespace vm
return g_locations[location].deallocator(addr);
}
u32 get_addr(const void* real_pointer)
{
const u64 diff = (u64)real_pointer - (u64)g_base_addr;
const u32 res = (u32)diff;
if (res == diff)
{
return res;
}
assert(!real_pointer);
return 0;
}
namespace ps3
{
u32 main_alloc(u32 size)

View File

@ -31,7 +31,7 @@ namespace vm
template<typename T = void>
T* const get_ptr(u32 addr)
{
return (T*)((u8*)g_base_addr + addr);
return reinterpret_cast<T*>(static_cast<u8*>(g_base_addr) + addr);
}
template<typename T>
@ -40,6 +40,8 @@ namespace vm
return *get_ptr<T>(addr);
}
u32 get_addr(const void* real_pointer);
template<typename T>
struct cast_ptr
{
@ -65,7 +67,7 @@ namespace vm
{
__forceinline static u32 cast(const u64 addr, const char* func)
{
const u32 res = (u32)addr;
const u32 res = static_cast<u32>(addr);
if (res != addr)
{
throw fmt::Format("%s(): invalid address 0x%llx", func, addr);
@ -96,42 +98,42 @@ namespace vm
static u8 read8(u32 addr)
{
return *((u8*)g_base_addr + addr);
return get_ref<u8>(addr);
}
static void write8(u32 addr, u8 value)
{
*((u8*)g_base_addr + addr) = value;
get_ref<u8>(addr) = value;
}
static u16 read16(u32 addr)
{
return re16(*(u16*)((u8*)g_base_addr + addr));
return get_ref<be_t<u16>>(addr);
}
static void write16(u32 addr, be_t<u16> value)
{
*(be_t<u16>*)((u8*)g_base_addr + addr) = value;
get_ref<be_t<u16>>(addr) = value;
}
static u32 read32(u32 addr)
{
return re32(*(u32*)((u8*)g_base_addr + addr));;
return get_ref<be_t<u32>>(addr);
}
static void write32(u32 addr, be_t<u32> value)
{
*(be_t<u32>*)((u8*)g_base_addr + addr) = value;
get_ref<be_t<u32>>(addr) = value;
}
static u64 read64(u32 addr)
{
return re64(*(u64*)((u8*)g_base_addr + addr));
return get_ref<be_t<u64>>(addr);
}
static void write64(u32 addr, be_t<u64> value)
{
*(be_t<u64>*)((u8*)g_base_addr + addr) = value;
get_ref<be_t<u64>>(addr) = value;
}
static void write16(u32 addr, u16 value)
@ -151,12 +153,12 @@ namespace vm
static u128 read128(u32 addr)
{
return re128(*(u128*)((u8*)g_base_addr + addr));
return get_ref<be_t<u128>>(addr);
}
static void write128(u32 addr, u128 value)
{
*(u128*)((u8*)g_base_addr + addr) = re128(value);
get_ref<be_t<u128>>(addr) = value;
}
}
@ -166,52 +168,52 @@ namespace vm
static u8 read8(u32 addr)
{
return *((u8*)g_base_addr + addr);
return get_ref<u8>(addr);
}
static void write8(u32 addr, u8 value)
{
*((u8*)g_base_addr + addr) = value;
get_ref<u8>(addr) = value;
}
static u16 read16(u32 addr)
{
return *(u16*)((u8*)g_base_addr + addr);
return get_ref<u16>(addr);
}
static void write16(u32 addr, u16 value)
{
*(u16*)((u8*)g_base_addr + addr) = value;
get_ref<u16>(addr) = value;
}
static u32 read32(u32 addr)
{
return *(u32*)((u8*)g_base_addr + addr);
return get_ref<u32>(addr);
}
static void write32(u32 addr, u32 value)
{
*(u32*)((u8*)g_base_addr + addr) = value;
get_ref<u32>(addr) = value;
}
static u64 read64(u32 addr)
{
return *(u64*)((u8*)g_base_addr + addr);
return get_ref<u64>(addr);
}
static void write64(u32 addr, u64 value)
{
*(u64*)((u8*)g_base_addr + addr) = value;
get_ref<u64>(addr) = value;
}
static u128 read128(u32 addr)
{
return *(u128*)((u8*)g_base_addr + addr);
return get_ref<u128>(addr);
}
static void write128(u32 addr, u128 value)
{
*(u128*)((u8*)g_base_addr + addr) = value;
get_ref<u128>(addr) = value;
}
}

View File

@ -11,7 +11,7 @@ namespace vm
public:
typedef typename std::remove_cv<T>::type type;
static const u32 address_size = (u32)sizeof(AT);
static const u32 address_size = sizeof(AT);
_ptr_base operator++ (int)
{
@ -76,13 +76,11 @@ namespace vm
return vm::get_ref<_ptr_base<T, lvl - 1, std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>>>(vm::cast(m_addr + sizeof(AT)* index));
}
//typedef typename invert_be_t<AT>::type AT2;
template<typename AT2>
operator const _ptr_base<T, lvl, AT2>() const
{
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
return (_ptr_base<T, lvl, AT2>&)addr;
const AT2 addr = convert_le_be<AT2>(m_addr);
return reinterpret_cast<const _ptr_base<T, lvl, AT2>&>(addr);
}
AT addr() const
@ -95,9 +93,9 @@ namespace vm
m_addr = value;
}
static _ptr_base make(AT addr)
static const _ptr_base make(const AT& addr)
{
return (_ptr_base&)addr;
return reinterpret_cast<const _ptr_base&>(addr);
}
_ptr_base& operator = (const _ptr_base& right) = default;
@ -110,7 +108,7 @@ namespace vm
public:
typedef typename std::remove_cv<T>::type type;
static const u32 data_size = (u32)sizeof(T);
static const u32 data_size = sizeof(T);
__forceinline T* const operator -> () const
{
@ -186,18 +184,6 @@ namespace vm
explicit operator bool() const { return m_addr != 0; }
explicit operator T*() const { return get_ptr(); }
/*
operator _ref_base<T, AT>()
{
return _ref_base<T, AT>::make(m_addr);
}
operator const _ref_base<T, AT>() const
{
return _ref_base<T, AT>::make(m_addr);
}
*/
AT addr() const
{
return m_addr;
@ -209,19 +195,11 @@ namespace vm
m_addr = convert_le_be<AT>(value);
}
/*
operator T*() const
{
return get_ptr();
}
*/
//typedef typename invert_be_t<AT>::type AT2;
template<typename AT2>
operator const _ptr_base<T, 1, AT2>() const
{
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
return (_ptr_base<T, 1, AT2>&)addr;
const AT2 addr = convert_le_be<AT2>(m_addr);
return reinterpret_cast<const _ptr_base<T, 1, AT2>&>(addr);
}
T* get_ptr() const
@ -229,9 +207,9 @@ namespace vm
return vm::get_ptr<T>(vm::cast(m_addr));
}
static _ptr_base make(AT addr)
static const _ptr_base make(const AT& addr)
{
return (_ptr_base&)addr;
return reinterpret_cast<const _ptr_base&>(addr);
}
_ptr_base& operator = (const _ptr_base& right) = default;
@ -273,25 +251,23 @@ namespace vm
__forceinline bool operator !=(const nullptr_t& right) const { return m_addr != 0; }
explicit operator bool() const { return m_addr != 0; }
//typedef typename invert_be_t<AT>::type AT2;
template<typename AT2>
operator const _ptr_base<void, 1, AT2>() const
{
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
return (_ptr_base<void, 1, AT2>&)addr;
const AT2 addr = convert_le_be<AT2>(m_addr);
return reinterpret_cast<const _ptr_base<void, 1, AT2>&>(addr);
}
template<typename AT2>
operator const _ptr_base<const void, 1, AT2>() const
{
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
return (_ptr_base<const void, 1, AT2>&)addr;
const AT2 addr = convert_le_be<AT2>(m_addr);
return reinterpret_cast<const _ptr_base<const void, 1, AT2>&>(addr);
}
static _ptr_base make(AT addr)
static const _ptr_base make(const AT& addr)
{
return (_ptr_base&)addr;
return reinterpret_cast<const _ptr_base&>(addr);
}
_ptr_base& operator = (const _ptr_base& right) = default;
@ -333,18 +309,16 @@ namespace vm
__forceinline bool operator !=(const nullptr_t& right) const { return m_addr != 0; }
explicit operator bool() const { return m_addr != 0; }
//typedef typename invert_be_t<AT>::type AT2;
template<typename AT2>
operator const _ptr_base<const void, 1, AT2>() const
{
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
return (_ptr_base<const void, 1, AT2>&)addr;
const AT2 addr = convert_le_be<AT2>(m_addr);
return reinterpret_cast<const _ptr_base<const void, 1, AT2>&>(addr);
}
static _ptr_base make(AT addr)
static const _ptr_base make(const AT& addr)
{
return (_ptr_base&)addr;
return reinterpret_cast<const _ptr_base&>(addr);
}
_ptr_base& operator = (const _ptr_base& right) = default;
@ -382,23 +356,21 @@ namespace vm
__forceinline bool operator !=(const nullptr_t& right) const { return m_addr != 0; }
explicit operator bool() const { return m_addr != 0; }
//typedef typename invert_be_t<AT>::type AT2;
template<typename AT2>
operator const _ptr_base<RT(*)(T...), 1, AT2>() const
{
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
return (_ptr_base<RT(*)(T...), 1, AT2>&)addr;
const AT2 addr = convert_le_be<AT2>(m_addr);
return reinterpret_cast<const _ptr_base<RT(*)(T...), 1, AT2>&>(addr);
}
static _ptr_base make(AT addr)
static const _ptr_base make(const AT& addr)
{
return (_ptr_base&)addr;
return reinterpret_cast<const _ptr_base&>(addr);
}
operator const std::function<RT(T...)>() const
{
typename std::remove_const<AT>::type addr = convert_le_be<AT>(m_addr);
const AT addr = convert_le_be<AT>(m_addr);
return [addr](T... args) -> RT { return make(addr)(args...); };
}
@ -408,75 +380,88 @@ namespace vm
//BE pointer to LE data
template<typename T, int lvl = 1, typename AT = u32> struct bptrl : public _ptr_base<T, lvl, typename to_be_t<AT>::type>
{
static bptrl make(AT addr)
static const bptrl make(AT addr)
{
return (bptrl&)addr;
auto res = _ptr_base<T, lvl, typename to_be_t<AT>::type>::make(convert_le_be<typename to_be_t<AT>::type>(addr));
return static_cast<const bptrl&>(res);
}
using _ptr_base<T, lvl, typename to_be_t<AT>::type>::operator=;
//using _ptr_base<T, lvl, typename to_be_t<AT>::type>::operator const _ptr_base<T, lvl, AT>;
};
//BE pointer to BE data
template<typename T, int lvl = 1, typename AT = u32> struct bptrb : public _ptr_base<typename to_be_t<T>::type, lvl, typename to_be_t<AT>::type>
{
static bptrb make(AT addr)
static const bptrb make(AT addr)
{
return (bptrb&)addr;
auto res = _ptr_base<typename to_be_t<T>::type, lvl, typename to_be_t<AT>::type>::make(convert_le_be<typename to_be_t<AT>::type>(addr));
return static_cast<const bptrb&>(res);
}
using _ptr_base<typename to_be_t<T>::type, lvl, typename to_be_t<AT>::type>::operator=;
//using _ptr_base<typename to_be_t<T>::type, lvl, typename to_be_t<AT>::type>::operator const _ptr_base<typename to_be_t<T>::type, lvl, AT>;
};
//LE pointer to BE data
template<typename T, int lvl = 1, typename AT = u32> struct lptrb : public _ptr_base<typename to_be_t<T>::type, lvl, AT>
{
static lptrb make(AT addr)
static const lptrb make(AT addr)
{
return (lptrb&)addr;
auto res = _ptr_base<typename to_be_t<T>::type, lvl, AT>::make(addr);
return static_cast<const lptrb&>(res);
}
using _ptr_base<typename to_be_t<T>::type, lvl, AT>::operator=;
//using _ptr_base<typename to_be_t<T>::type, lvl, AT>::operator const _ptr_base<typename to_be_t<T>::type, lvl, typename to_be_t<AT>::type>;
};
//LE pointer to LE data
template<typename T, int lvl = 1, typename AT = u32> struct lptrl : public _ptr_base<T, lvl, AT>
{
static lptrl make(AT addr)
static const lptrl make(AT addr)
{
return (lptrl&)addr;
auto res = _ptr_base<T, lvl, AT>::make(addr);
return static_cast<const lptrl&>(res);
}
using _ptr_base<T, lvl, AT>::operator=;
//using _ptr_base<T, lvl, AT>::operator const _ptr_base<T, lvl, typename to_be_t<AT>::type>;
};
namespace ps3
{
template<typename T, int lvl = 1, typename AT = u32> struct ptr;
template<typename T, int lvl = 1, typename AT = u32> struct bptr;
//default pointer for HLE functions (LE pointer to BE data)
template<typename T, int lvl = 1, typename AT = u32> struct ptr : public lptrb<T, lvl, AT>
template<typename T, int lvl, typename AT> struct ptr : public lptrb<T, lvl, AT>
{
static ptr make(AT addr)
static const ptr make(AT addr)
{
return (ptr&)addr;
auto res = lptrb<T, lvl, AT>::make(addr);
return static_cast<const ptr&>(res);
}
vm::ps3::bptr<T, lvl, AT> to_be() const
{
return vm::ps3::bptr<T, lvl, AT>::make(this->addr());
}
using lptrb<T, lvl, AT>::operator=;
//using lptrb<T, lvl, AT>::operator const _ptr_base<typename to_be_t<T>::type, lvl, AT>;
};
//default pointer for HLE structures (BE pointer to BE data)
template<typename T, int lvl = 1, typename AT = u32> struct bptr : public bptrb<T, lvl, AT>
template<typename T, int lvl, typename AT> struct bptr : public bptrb<T, lvl, AT>
{
static bptr make(AT addr)
static const bptr make(AT addr)
{
return (bptr&)addr;
auto res = bptrb<T, lvl, AT>::make(addr);
return static_cast<const bptr&>(res);
}
vm::ps3::ptr<T, lvl, AT> to_le() const
{
return vm::ps3::ptr<T, lvl, AT>::make(this->addr());
}
using bptrb<T, lvl, AT>::operator=;
//using bptrb<T, lvl, AT>::operator const _ptr_base<typename to_be_t<T>::type, lvl, AT>;
};
}
@ -485,9 +470,10 @@ namespace vm
//default pointer for HLE functions & structures (LE pointer to LE data)
template<typename T, int lvl = 1, typename AT = u32> struct ptr : public lptrl<T, lvl, AT>
{
static ptr make(AT addr)
static const ptr make(AT addr)
{
return (ptr&)addr;
auto res = lptrl<T, lvl, AT>::make(addr);
return static_cast<const ptr&>(res);
}
using lptrl<T, lvl, AT>::operator=;
@ -501,33 +487,75 @@ namespace vm
namespace fmt
{
// external specializations for fmt::format function
namespace detail
{
template<typename T, int lvl, typename AT>
struct get_fmt<vm::ps3::ptr<T, lvl, AT>, false>
struct unveil<vm::ps3::ptr<T, lvl, AT>, false>
{
__forceinline static std::string text(const char* fmt, size_t len, const vm::ps3::ptr<T, lvl, AT>& arg)
typedef typename unveil<AT>::result_type result_type;
__forceinline static result_type get_value(const vm::ps3::ptr<T, lvl, AT>& arg)
{
return get_fmt<AT>::text(fmt, len, arg.addr());
return unveil<AT>::get_value(arg.addr());
}
};
template<typename T, int lvl, typename AT>
struct get_fmt<vm::ps3::bptr<T, lvl, AT>, false>
struct unveil<vm::ps3::bptr<T, lvl, AT>, false>
{
__forceinline static std::string text(const char* fmt, size_t len, const vm::ps3::bptr<T, lvl, AT>& arg)
typedef typename unveil<AT>::result_type result_type;
__forceinline static result_type get_value(const vm::ps3::bptr<T, lvl, AT>& arg)
{
return get_fmt<AT>::text(fmt, len, arg.addr());
return unveil<AT>::get_value(arg.addr());
}
};
template<typename T, int lvl, typename AT>
struct get_fmt<vm::psv::ptr<T, lvl, AT>, false>
struct unveil<vm::psv::ptr<T, lvl, AT>, false>
{
__forceinline static std::string text(const char* fmt, size_t len, const vm::psv::ptr<T, lvl, AT>& arg)
typedef typename unveil<AT>::result_type result_type;
__forceinline static result_type get_value(const vm::psv::ptr<T, lvl, AT>& arg)
{
return get_fmt<AT>::text(fmt, len, arg.addr());
return unveil<AT>::get_value(arg.addr());
}
};
}
// external specializations for PPU GPR (SC_FUNC.h, CB_FUNC.h)
template<typename T, bool is_enum>
struct cast_ppu_gpr;
template<typename T, int lvl, typename AT>
struct cast_ppu_gpr<vm::ps3::ptr<T, lvl, AT>, false>
{
__forceinline static u64 to_gpr(const vm::ps3::ptr<T, lvl, AT>& value)
{
return value.addr();
}
__forceinline static vm::ps3::ptr<T, lvl, AT> from_gpr(const u64 reg)
{
return vm::ps3::ptr<T, lvl, AT>::make(cast_ppu_gpr<AT, std::is_enum<AT>::value>::from_gpr(reg));
}
};
// external specializations for ARMv7 GPR
template<typename T, bool is_enum>
struct cast_armv7_gpr;
template<typename T, int lvl, typename AT>
struct cast_armv7_gpr<vm::psv::ptr<T, lvl, AT>, false>
{
__forceinline static u32 to_gpr(const vm::psv::ptr<T, lvl, AT>& value)
{
return value.addr();
}
__forceinline static vm::psv::ptr<T, lvl, AT> from_gpr(const u32 reg)
{
return vm::psv::ptr<T, lvl, AT>::make(cast_armv7_gpr<AT, std::is_enum<AT>::value>::from_gpr(reg));
}
};

View File

@ -28,9 +28,9 @@ namespace vm
return m_addr;
}
static _ref_base make(AT addr)
static _ref_base make(const AT& addr)
{
return (_ref_base&)addr;
return reinterpret_cast<_ref_base&>(addr);
}
_ref_base& operator = (le_type right)
@ -113,33 +113,75 @@ namespace vm
namespace fmt
{
// external specializations for fmt::format function
namespace detail
{
template<typename T, typename AT>
struct get_fmt<vm::ps3::ref<T, AT>, false>
struct unveil<vm::ps3::ref<T, AT>, false>
{
__forceinline static std::string text(const char* fmt, size_t len, const vm::ps3::ref<T, AT>& arg)
typedef typename unveil<AT>::result_type result_type;
__forceinline static result_type get_value(const vm::ps3::ref<T, AT>& arg)
{
return get_fmt<AT>::text(fmt, len, arg.addr());
return unveil<AT>::get_value(arg.addr());
}
};
template<typename T, typename AT>
struct get_fmt<vm::ps3::bref<T, AT>, false>
struct unveil<vm::ps3::bref<T, AT>, false>
{
__forceinline static std::string text(const char* fmt, size_t len, const vm::ps3::bref<T, AT>& arg)
typedef typename unveil<AT>::result_type result_type;
__forceinline static result_type get_value(const vm::ps3::bref<T, AT>& arg)
{
return get_fmt<AT>::text(fmt, len, arg.addr());
return unveil<AT>::get_value(arg.addr());
}
};
template<typename T, typename AT>
struct get_fmt<vm::psv::ref<T, AT>, false>
struct unveil<vm::psv::ref<T, AT>, false>
{
__forceinline static std::string text(const char* fmt, size_t len, const vm::psv::ref<T, AT>& arg)
typedef typename unveil<AT>::result_type result_type;
__forceinline static result_type get_value(const vm::psv::ref<T, AT>& arg)
{
return get_fmt<AT>::text(fmt, len, arg.addr());
return unveil<AT>::get_value(arg.addr());
}
};
}
// external specializations for PPU GPR (SC_FUNC.h, CB_FUNC.h)
template<typename T, bool is_enum>
struct cast_ppu_gpr;
template<typename T, typename AT>
struct cast_ppu_gpr<vm::ps3::ref<T, AT>, false>
{
__forceinline static u64 to_gpr(const vm::ps3::ref<T, AT>& value)
{
return value.addr();
}
__forceinline static vm::ps3::ref<T, AT> from_gpr(const u64 reg)
{
return vm::ps3::ref<T, AT>::make(cast_ppu_gpr<AT, std::is_enum<AT>::value>::from_gpr(reg));
}
};
// external specializations for ARMv7 GPR
template<typename T, bool is_enum>
struct cast_armv7_gpr;
template<typename T, typename AT>
struct cast_armv7_gpr<vm::psv::ref<T, AT>, false>
{
__forceinline static u32 to_gpr(const vm::psv::ref<T, AT>& value)
{
return value.addr();
}
__forceinline static vm::psv::ref<T, AT> from_gpr(const u32 reg)
{
return vm::psv::ref<T, AT>::make(cast_armv7_gpr<AT, std::is_enum<AT>::value>::from_gpr(reg));
}
};

View File

@ -35,7 +35,7 @@ namespace vm
void alloc()
{
m_addr = (u32)Memory.Alloc(size(), m_align);
m_addr = vm::cast(Memory.Alloc(size(), m_align));
m_ptr = vm::get_ptr<T>(m_addr);
}
@ -162,7 +162,7 @@ namespace vm
void alloc()
{
m_addr = (u32)Memory.Alloc(size(), m_align);
m_addr = vm::cast(Memory.Alloc(size(), m_align));
m_ptr = vm::get_ptr<T>(m_addr);
}

View File

@ -2505,7 +2505,7 @@ u32 RSXThread::ReadIO32(u32 addr)
u32 value;
if (!Memory.RSXIOMem.Read32(addr, &value))
{
throw fmt::Format("%s(rsxio_addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr);
throw fmt::Format("%s(addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr);
}
return value;
}
@ -2514,6 +2514,6 @@ void RSXThread::WriteIO32(u32 addr, u32 value)
{
if (!Memory.RSXIOMem.Write32(addr, value))
{
throw fmt::Format("%s(rsxio_addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr);
throw fmt::Format("%s(addr=0x%x): RSXIO memory not mapped", __FUNCTION__, addr);
}
}

View File

@ -37,7 +37,7 @@ namespace cb_detail
__forceinline static void set_value(PPUThread& CPU, const T& arg)
{
CPU.FPR[f_count] = arg;
CPU.FPR[f_count] = static_cast<T>(arg);
}
};
@ -101,7 +101,7 @@ namespace cb_detail
__forceinline static T get_value(const PPUThread& CPU)
{
return (T&)CPU.GPR[3];
return cast_from_ppu_gpr<T>(CPU.GPR[3]);
}
};
@ -112,7 +112,7 @@ namespace cb_detail
__forceinline static T get_value(const PPUThread& CPU)
{
return (T)CPU.FPR[1];
return static_cast<T>(CPU.FPR[1]);
}
};
@ -181,13 +181,13 @@ namespace vm
}
template<typename RT, typename... T>
RT cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
__forceinline RT cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
{
return cb_detail::_func_caller<RT, T...>::call(CPU, pc, rtoc, args...);
}
template<typename... T>
void cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
{
cb_detail::_func_caller<void, T...>::call(CPU, pc, rtoc, args...);
}
//template<typename... T>
//void cb_call(PPUThread& CPU, u32 pc, u32 rtoc, T... args)
//{
// cb_detail::_func_caller<void, T...>::call(CPU, pc, rtoc, args...);
//}

View File

@ -9,25 +9,15 @@ bool LogBase::CheckLogging() const
return Ini.HLELogging.GetValue() || m_logging;
}
void LogBase::LogOutput(LogType type, const char* info, const std::string& text) const
void LogBase::LogOutput(LogType type, const std::string& text) const
{
switch (type)
{
case LogNotice: LOG_NOTICE(HLE, "%s%s%s", GetName().c_str(), info, text.c_str()); break;
case LogSuccess: LOG_SUCCESS(HLE, "%s%s%s", GetName().c_str(), info, text.c_str()); break;
case LogWarning: LOG_WARNING(HLE, "%s%s%s", GetName().c_str(), info, text.c_str()); break;
case LogError: LOG_ERROR(HLE, "%s%s%s", GetName().c_str(), info, text.c_str()); break;
}
}
void LogBase::LogOutput(LogType type, const u32 id, const char* info, const std::string& text) const
{
switch (type)
{
case LogNotice: LOG_NOTICE(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break;
case LogSuccess: LOG_SUCCESS(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break;
case LogWarning: LOG_WARNING(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break;
case LogError: LOG_ERROR(HLE, "%s[%d]%s%s", GetName().c_str(), id, info, text.c_str()); break;
case LogNotice: LOG_NOTICE(HLE, GetName() + ": " + text); break;
case LogSuccess: LOG_SUCCESS(HLE, GetName() + ": " + text); break;
case LogWarning: LOG_WARNING(HLE, GetName() + ": " + text); break;
case LogError: LOG_ERROR(HLE, GetName() + " error: " + text); break;
case LogTodo: LOG_ERROR(HLE, GetName() + " TODO: " + text); break;
}
}

View File

@ -11,10 +11,16 @@ class LogBase
LogSuccess,
LogWarning,
LogError,
LogTodo,
};
void LogOutput(LogType type, const char* info, const std::string& text) const;
void LogOutput(LogType type, const u32 id, const char* info, const std::string& text) const;
void LogOutput(LogType type, const std::string& text) const;
template<typename... Targs>
__noinline void LogPrepare(LogType type, const char* fmt, size_t len, Targs... args) const
{
LogOutput(type, fmt::detail::format(fmt, len, args...));
}
public:
void SetLogging(bool value)
@ -29,17 +35,14 @@ public:
virtual const std::string& GetName() const = 0;
template<typename... Targs> __noinline void Notice(const u32 id, const char* fmt, Targs... args) const
template<typename... Targs>
__forceinline void Notice(const char* fmt, Targs... args) const
{
LogOutput(LogNotice, id, " : ", fmt::format(fmt, args...));
LogPrepare(LogNotice, fmt, strlen(fmt), fmt::do_unveil(args)...);
}
template<typename... Targs> __noinline void Notice(const char* fmt, Targs... args) const
{
LogOutput(LogNotice, ": ", fmt::format(fmt, args...));
}
template<typename... Targs> __forceinline void Log(const char* fmt, Targs... args) const
template<typename... Targs>
__forceinline void Log(const char* fmt, Targs... args) const
{
if (CheckLogging())
{
@ -47,52 +50,28 @@ public:
}
}
template<typename... Targs> __forceinline void Log(const u32 id, const char* fmt, Targs... args) const
template<typename... Targs>
__forceinline void Success(const char* fmt, Targs... args) const
{
if (CheckLogging())
{
Notice(id, fmt, args...);
}
LogPrepare(LogSuccess, fmt, strlen(fmt), fmt::do_unveil(args)...);
}
template<typename... Targs> __noinline void Success(const u32 id, const char* fmt, Targs... args) const
template<typename... Targs>
__forceinline void Warning(const char* fmt, Targs... args) const
{
LogOutput(LogSuccess, id, " : ", fmt::format(fmt, args...));
LogPrepare(LogWarning, fmt, strlen(fmt), fmt::do_unveil(args)...);
}
template<typename... Targs> __noinline void Success(const char* fmt, Targs... args) const
template<typename... Targs>
__forceinline void Error(const char* fmt, Targs... args) const
{
LogOutput(LogSuccess, ": ", fmt::format(fmt, args...));
LogPrepare(LogError, fmt, strlen(fmt), fmt::do_unveil(args)...);
}
template<typename... Targs> __noinline void Warning(const u32 id, const char* fmt, Targs... args) const
template<typename... Targs>
__forceinline void Todo(const char* fmt, Targs... args) const
{
LogOutput(LogWarning, id, " warning: ", fmt::format(fmt, args...));
}
template<typename... Targs> __noinline void Warning(const char* fmt, Targs... args) const
{
LogOutput(LogWarning, " warning: ", fmt::format(fmt, args...));
}
template<typename... Targs> __noinline void Error(const u32 id, const char* fmt, Targs... args) const
{
LogOutput(LogError, id, " error: ", fmt::format(fmt, args...));
}
template<typename... Targs> __noinline void Error(const char* fmt, Targs... args) const
{
LogOutput(LogError, " error: ", fmt::format(fmt, args...));
}
template<typename... Targs> __noinline void Todo(const u32 id, const char* fmt, Targs... args) const
{
LogOutput(LogError, id, " TODO: ", fmt::format(fmt, args...));
}
template<typename... Targs> __noinline void Todo(const char* fmt, Targs... args) const
{
LogOutput(LogError, " TODO: ", fmt::format(fmt, args...));
LogPrepare(LogTodo, fmt, strlen(fmt), fmt::do_unveil(args)...);
}
};

View File

@ -529,7 +529,7 @@ int cellAdecOpen(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResource> res, vm::
if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG;
*handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, vm::ptr<CellAdecCbMsg>::make(cb->cbFunc.addr()), cb->cbArg));
*handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc.to_le(), cb->cbArg));
return CELL_OK;
}
@ -541,7 +541,7 @@ int cellAdecOpenEx(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res,
if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG;
*handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, vm::ptr<CellAdecCbMsg>::make(cb->cbFunc.addr()), cb->cbArg));
*handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc.to_le(), cb->cbArg));
return CELL_OK;
}

View File

@ -1067,5 +1067,5 @@ void cellAudio_init(Module *pxThis)
void cellAudio_load()
{
// never called :(
// CELL_SYSMODULE AUDIO module is rarely loaded manually, so cellAudio_load() won't be called in every case
}

View File

@ -803,7 +803,7 @@ int cellDmuxOpen(vm::ptr<const CellDmuxType> demuxerType, vm::ptr<const CellDmux
// TODO: check demuxerResource and demuxerCb arguments
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResource->memAddr, demuxerResource->memSize, vm::ptr<CellDmuxCbMsg>::make(demuxerCb->cbMsgFunc.addr()), demuxerCb->cbArg));
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResource->memAddr, demuxerResource->memSize, demuxerCb->cbMsgFunc.to_le(), demuxerCb->cbArg));
return CELL_OK;
}
@ -821,7 +821,7 @@ int cellDmuxOpenEx(vm::ptr<const CellDmuxType> demuxerType, vm::ptr<const CellDm
// TODO: check demuxerResourceEx and demuxerCb arguments
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResourceEx->memAddr, demuxerResourceEx->memSize, vm::ptr<CellDmuxCbMsg>::make(demuxerCb->cbMsgFunc.addr()), demuxerCb->cbArg));
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResourceEx->memAddr, demuxerResourceEx->memSize, demuxerCb->cbMsgFunc.to_le(), demuxerCb->cbArg));
return CELL_OK;
}
@ -839,7 +839,7 @@ int cellDmuxOpen2(vm::ptr<const CellDmuxType2> demuxerType2, vm::ptr<const CellD
// TODO: check demuxerType2, demuxerResource2 and demuxerCb arguments
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResource2->memAddr, demuxerResource2->memSize, vm::ptr<CellDmuxCbMsg>::make(demuxerCb->cbMsgFunc.addr()), demuxerCb->cbArg));
*demuxerHandle = dmuxOpen(new Demuxer(demuxerResource2->memAddr, demuxerResource2->memSize, demuxerCb->cbMsgFunc.to_le(), demuxerCb->cbArg));
return CELL_OK;
}
@ -988,14 +988,14 @@ int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr<const CellCodecEsFilterId> esFil
std::shared_ptr<ElementaryStream> es(new ElementaryStream(dmux.get(), esResourceInfo->memAddr, esResourceInfo->memSize,
esFilterId->filterIdMajor, esFilterId->filterIdMinor, esFilterId->supplementalInfo1, esFilterId->supplementalInfo2,
vm::ptr<CellDmuxCbEsMsg>::make(esCb->cbEsMsgFunc.addr()), esCb->cbArg, esSpecificInfo_addr));
esCb->cbEsMsgFunc.to_le(), esCb->cbArg, esSpecificInfo_addr));
u32 id = cellDmux->GetNewId(es);
es->id = id;
*esHandle = id;
cellDmux->Warning("*** New ES(dmux=%d, addr=0x%x, size=0x%x, filter(0x%x, 0x%x, 0x%x, 0x%x), cb=0x%x(arg=0x%x), spec=0x%x): id = %d",
demuxerHandle, es->memAddr, es->memSize, es->fidMajor, es->fidMinor, es->sup1, es->sup2, esCb->cbEsMsgFunc, es->cbArg, es->spec, id);
demuxerHandle, es->memAddr, es->memSize, es->fidMajor, es->fidMinor, es->sup1, es->sup2, es->cbFunc, es->cbArg, es->spec, id);
DemuxerTask task(dmuxEnableEs);
task.es.es = id;

View File

@ -443,11 +443,11 @@ int cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::ptr<const char>
std::string errorMsg;
if (type == CELL_GAME_ERRDIALOG_NOSPACE || type == CELL_GAME_ERRDIALOG_NOSPACE_EXIT)
{
errorMsg = fmt::Format("ERROR: %s\nSpace needed: %d KB", errorName.c_str(), errNeedSizeKB, dirName);
errorMsg = fmt::format("ERROR: %s\nSpace needed: %d KB", errorName, errNeedSizeKB);
}
else
{
errorMsg = fmt::Format("ERROR: %s", errorName.c_str());
errorMsg = fmt::format("ERROR: %s", errorName);
}
if (dirName)

View File

@ -39,7 +39,7 @@ int cellGifDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellGifDecSrc
case se32(CELL_GIFDEC_FILE):
// Get file descriptor
vm::var<be_t<u32>> fd;
int ret = cellFsOpen(vm::ptr<const char>::make(src->fileName.addr()), 0, fd, vm::ptr<u32>::make(0), 0);
int ret = cellFsOpen(src->fileName.to_le(), 0, fd, vm::ptr<const void>::make(0), 0);
current_subHandle->fd = fd.value();
if (ret != CELL_OK) return CELL_GIFDEC_ERROR_OPEN_FILE;

View File

@ -45,7 +45,7 @@ int cellJpgDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellJpgDecSrc
case se32(CELL_JPGDEC_FILE):
// Get file descriptor
vm::var<be_t<u32>> fd;
int ret = cellFsOpen(vm::ptr<const char>::make(src->fileName.addr()), 0, fd, vm::ptr<u32>::make(0), 0);
int ret = cellFsOpen(src->fileName.to_le(), 0, fd, vm::ptr<const void>::make(0), 0);
current_subHandle->fd = fd.value();
if (ret != CELL_OK) return CELL_JPGDEC_ERROR_OPEN_FILE;

View File

@ -86,7 +86,7 @@ s64 pngDecOpen(
case se32(CELL_PNGDEC_FILE):
// Get file descriptor
vm::var<be_t<u32>> fd;
int ret = cellFsOpen(vm::ptr<const char>::make(src->fileName.addr()), 0, fd, vm::ptr<u32>::make(0), 0);
int ret = cellFsOpen(src->fileName.to_le(), 0, fd, vm::ptr<const void>::make(0), 0);
stream->fd = fd.value();
if (ret != CELL_OK) return CELL_PNGDEC_ERROR_OPEN_FILE;

View File

@ -205,7 +205,7 @@ void getSaveDataStat(SaveDataEntry entry, vm::ptr<CellSaveDataStatGet> statGet)
strcpy_trunc(statGet->getParam.listParam, entry.listParam);
statGet->fileNum = 0;
statGet->fileList.set(be_t<u32>::make(0));
statGet->fileList.set(0);
statGet->fileListNum = 0;
std::string saveDir = "/dev_hdd0/home/00000001/savedata/" + entry.dirName; // TODO: Get the path of the current user
vfsDir dir(saveDir);
@ -242,7 +242,7 @@ void getSaveDataStat(SaveDataEntry entry, vm::ptr<CellSaveDataStatGet> statGet)
}
}
statGet->fileList = vm::ptr<CellSaveDataFileStat>::make((u32)Memory.Alloc(sizeof(CellSaveDataFileStat) * fileEntries.size(), 8));
statGet->fileList.set((u32)Memory.Alloc(sizeof(CellSaveDataFileStat) * fileEntries.size(), 8));
for (u32 i = 0; i < fileEntries.size(); i++) {
CellSaveDataFileStat *dst = &statGet->fileList[i];
memcpy(dst, &fileEntries[i], sizeof(CellSaveDataFileStat));
@ -366,8 +366,8 @@ s32 cellSaveDataListSave2(
// Sort the entries and fill the listGet->dirList array
std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder));
listGet->dirList = vm::bptr<CellSaveDataDirList>::make(setBuf->buf.addr());
auto dirList = vm::get_ptr<CellSaveDataDirList>(listGet->dirList.addr());
listGet->dirList.set(setBuf->buf.addr());
auto dirList = listGet->dirList.get_ptr();
for (u32 i=0; i<saveEntries.size(); i++) {
strcpy_trunc(dirList[i].dirName, saveEntries[i].dirName);
@ -382,9 +382,9 @@ s32 cellSaveDataListSave2(
return CELL_SAVEDATA_ERROR_CBRESULT;
}
setSaveDataList(saveEntries, vm::ptr<CellSaveDataDirList>::make(listSet->fixedList.addr()), listSet->fixedListNum);
setSaveDataList(saveEntries, listSet->fixedList.to_le(), listSet->fixedListNum);
if (listSet->newData)
addNewSaveDataEntry(saveEntries, vm::ptr<CellSaveDataListNewData>::make(listSet->newData.addr()));
addNewSaveDataEntry(saveEntries, listSet->newData.to_le());
if (saveEntries.size() == 0) {
cellSysutil->Error("cellSaveDataListSave2: No save entries found!"); // TODO: Find a better way to handle this error
return CELL_OK;
@ -458,8 +458,8 @@ s32 cellSaveDataListLoad2(
// Sort the entries and fill the listGet->dirList array
std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder));
listGet->dirList = vm::bptr<CellSaveDataDirList>::make(setBuf->buf.addr());
auto dirList = vm::get_ptr<CellSaveDataDirList>(listGet->dirList.addr());
listGet->dirList.set(setBuf->buf.addr());
auto dirList = listGet->dirList.get_ptr();
for (u32 i=0; i<saveEntries.size(); i++) {
strcpy_trunc(dirList[i].dirName, saveEntries[i].dirName);
@ -474,9 +474,9 @@ s32 cellSaveDataListLoad2(
return CELL_SAVEDATA_ERROR_CBRESULT;
}
setSaveDataList(saveEntries, vm::ptr<CellSaveDataDirList>::make(listSet->fixedList.addr()), listSet->fixedListNum);
setSaveDataList(saveEntries, listSet->fixedList.to_le(), listSet->fixedListNum);
if (listSet->newData)
addNewSaveDataEntry(saveEntries, vm::ptr<CellSaveDataListNewData>::make(listSet->newData.addr()));
addNewSaveDataEntry(saveEntries, listSet->newData.to_le());
if (saveEntries.size() == 0) {
cellSysutil->Error("cellSaveDataListLoad2: No save entries found!"); // TODO: Find a better way to handle this error
return CELL_OK;
@ -548,8 +548,8 @@ s32 cellSaveDataFixedSave2(
// Sort the entries and fill the listGet->dirList array
std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder));
listGet->dirList = vm::bptr<CellSaveDataDirList>::make(setBuf->buf.addr());
auto dirList = vm::get_ptr<CellSaveDataDirList>(listGet->dirList.addr());
listGet->dirList.set(setBuf->buf.addr());
auto dirList = listGet->dirList.get_ptr();
for (u32 i = 0; i<saveEntries.size(); i++) {
strcpy_trunc(dirList[i].dirName, saveEntries[i].dirName);
strcpy_trunc(dirList[i].listParam, saveEntries[i].listParam);
@ -624,8 +624,8 @@ s32 cellSaveDataFixedLoad2(
// Sort the entries and fill the listGet->dirList array
std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder));
listGet->dirList = vm::bptr<CellSaveDataDirList>::make(setBuf->buf.addr());
auto dirList = vm::get_ptr<CellSaveDataDirList>(listGet->dirList.addr());
listGet->dirList.set(setBuf->buf.addr());
auto dirList = listGet->dirList.get_ptr();
for (u32 i = 0; i<saveEntries.size(); i++) {
strcpy_trunc(dirList[i].dirName, saveEntries[i].dirName);
strcpy_trunc(dirList[i].listParam, saveEntries[i].listParam);

View File

@ -66,7 +66,7 @@ s64 spursInit(
{
#ifdef PRX_DEBUG_XXX
return cb_call<s32, vm::ptr<CellSpurs>, u32, u32, s32, s32, s32, u32, u32, u32, u32, u32, u32, u32>(GetCurrentPPUThread(), libsre + 0x74E4, libsre_rtoc,
spurs, revision, sdkVersion, nSpus, spuPriority, ppuPriority, flags, Memory.RealToVirtualAddr(prefix), prefixSize, container, Memory.RealToVirtualAddr(swlPriority), swlMaxSpu, swlIsPreem);
spurs, revision, sdkVersion, nSpus, spuPriority, ppuPriority, flags, vm::get_addr(prefix), prefixSize, container, vm::get_addr(swlPriority), swlMaxSpu, swlIsPreem);
#endif
// SPURS initialization (asserts should actually rollback and return the error instead)
@ -700,7 +700,7 @@ s64 spursInit(
s32 res = CELL_OK;
#ifdef PRX_DEBUG
res = cb_call<s32, vm::ptr<CellSpurs>, u32, u32, u32>(GetCurrentPPUThread(), libsre + 0x10428, libsre_rtoc,
spurs, Memory.RealToVirtualAddr(swlPriority), swlMaxSpu, swlIsPreem);
spurs, vm::get_addr(swlPriority), swlMaxSpu, swlIsPreem);
#endif
assert(res == CELL_OK);
}
@ -1327,7 +1327,7 @@ s32 spursAddWorkload(
{
#ifdef PRX_DEBUG_XXX
return cb_call<s32, vm::ptr<CellSpurs>, vm::ptr<u32>, vm::ptr<const void>, u32, u64, u32, u32, u32, u32, u32, u32, u32>(GetCurrentPPUThread(), libsre + 0x96EC, libsre_rtoc,
spurs, wid, pm, size, data, Memory.RealToVirtualAddr(priorityTable), minContention, maxContention,
spurs, wid, pm, size, data, vm::get_addr(priorityTable), minContention, maxContention,
nameClass.addr(), nameInstance.addr(), hook.addr(), hookArg.addr());
#endif
@ -1752,7 +1752,7 @@ s64 cellSpursGetWorkloadFlag(vm::ptr<CellSpurs> spurs, vm::ptr<vm::bptr<CellSpur
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
}
flag->set(Memory.RealToVirtualAddr(&spurs->m.wklFlag));
flag->set(vm::get_addr(&spurs->m.wklFlag));
return CELL_OK;
}

View File

@ -367,12 +367,12 @@ struct CellSpurs
__forceinline vm::ptr<sys_lwmutex_t> get_lwmutex()
{
return vm::ptr<sys_lwmutex_t>::make(Memory.RealToVirtualAddr(&m.mutex));
return vm::ptr<sys_lwmutex_t>::make(vm::get_addr(&m.mutex));
}
__forceinline vm::ptr<sys_lwcond_t> get_lwcond()
{
return vm::ptr<sys_lwcond_t>::make(Memory.RealToVirtualAddr(&m.cond));
return vm::ptr<sys_lwcond_t>::make(vm::get_addr(&m.cond));
}
};

View File

@ -321,7 +321,6 @@ s32 syncRwmReadEndOp(CellSyncRwm::data_t& rwm)
{
if (!rwm.m_readers.data())
{
cellSync->Error("syncRwmReadEndOp(rwm_addr=0x%x): m_readers == 0 (m_writers=%d)", Memory.RealToVirtualAddr(&rwm), (u16)rwm.m_writers);
return CELL_SYNC_ERROR_ABORT;
}
@ -354,6 +353,7 @@ s32 cellSyncRwmRead(vm::ptr<CellSyncRwm> rwm, vm::ptr<void> buffer)
// prx: decrease m_readers (return 0x8041010C if already zero)
if (s32 res = rwm->data.atomic_op(CELL_OK, syncRwmReadEndOp))
{
cellSync->Error("syncRwmReadEndOp(rwm=0x%x) failed: m_readers == 0", rwm);
return res;
}

View File

@ -575,7 +575,7 @@ int cellVdecOpen(vm::ptr<const CellVdecType> type, vm::ptr<const CellVdecResourc
cellVdec->Warning("cellVdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)",
type.addr(), res.addr(), cb.addr(), handle.addr());
*handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, vm::ptr<CellVdecCbMsg>::make(cb->cbFunc.addr()), cb->cbArg));
*handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc.to_le(), cb->cbArg));
return CELL_OK;
}
@ -585,7 +585,7 @@ int cellVdecOpenEx(vm::ptr<const CellVdecTypeEx> type, vm::ptr<const CellVdecRes
cellVdec->Warning("cellVdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)",
type.addr(), res.addr(), cb.addr(), handle.addr());
*handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, vm::ptr<CellVdecCbMsg>::make(cb->cbFunc.addr()), cb->cbArg));
*handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc.to_le(), cb->cbArg));
return CELL_OK;
}

View File

@ -60,13 +60,13 @@ u32 cellSoundSynth2GetAddr(u16 reg)
int cellSoundSynth2SetEffectAttr(s16 bus, vm::ptr<CellSoundSynth2EffectAttr> attr)
{
libsynth2.Todo("cellSoundSynth2SetEffectAttr(bus=%d, attr_addr=0x%x)", bus, attr.addr());
libsynth2.Todo("cellSoundSynth2SetEffectAttr(bus=%d, attr=0x%x)", bus, attr);
return CELL_OK;
}
int cellSoundSynth2SetEffectMode(s16 bus, vm::ptr<CellSoundSynth2EffectAttr> attr)
{
libsynth2.Todo("cellSoundSynth2SetEffectMode(bus=%d, attr_addr=0x%x)", bus, attr.addr());
libsynth2.Todo("cellSoundSynth2SetEffectMode(bus=%d, attr=0x%x)", bus, attr);
return CELL_OK;
}
@ -77,8 +77,7 @@ void cellSoundSynth2SetCoreAttr(u16 entry, u16 value)
int cellSoundSynth2Generate(u16 samples, u32 L_addr, u32 R_addr, u32 Lr_addr, u32 Rr_addr)
{
libsynth2.Todo("cellSoundSynth2Generate(samples=0x%x, left=0x%x, right=0x%x, left_rear=0x%x, right_rear=0x%x)",
samples, L_addr, R_addr, Lr_addr, Rr_addr);
libsynth2.Todo("cellSoundSynth2Generate(samples=0x%x, left=0x%x, right=0x%x, left_rear=0x%x, right_rear=0x%x)", samples, L_addr, R_addr, Lr_addr, Rr_addr);
return CELL_OK;
}

View File

@ -8,7 +8,7 @@ public:
virtual ~func_caller(){};
};
namespace detail
namespace ppu_func_detail
{
enum bind_arg_type
{
@ -28,7 +28,7 @@ namespace detail
static __forceinline T func(PPUThread& CPU)
{
return (T&)CPU.GPR[g_count + 2];
return cast_from_ppu_gpr<T>(CPU.GPR[g_count + 2]);
}
};
@ -39,7 +39,7 @@ namespace detail
static __forceinline T func(PPUThread& CPU)
{
return (T)CPU.FPR[f_count];
return static_cast<T>(CPU.FPR[f_count]);
}
};
@ -65,7 +65,7 @@ namespace detail
{
// TODO: check stack argument displacement
const u64 res = CPU.GetStackArg(8 + std::max(g_count - 8, 0) + std::max(f_count - 13, 0) + std::max(v_count - 12, 0));
return (T&)res;
return cast_from_ppu_gpr<T>(res);
}
};
@ -88,7 +88,7 @@ namespace detail
static __forceinline void func(PPUThread& CPU, const T& result)
{
CPU.FPR[1] = result;
CPU.FPR[1] = static_cast<T>(result);
}
};
@ -122,21 +122,21 @@ namespace detail
};
template <typename RT, typename F, typename Tuple>
static __forceinline RT call(F f, Tuple && t)
__forceinline RT call(F f, Tuple && t)
{
typedef typename std::decay<Tuple>::type ttype;
return detail::call_impl<RT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
return ppu_func_detail::call_impl<RT, F, Tuple, 0 == std::tuple_size<ttype>::value, std::tuple_size<ttype>::value>::call(f, std::forward<Tuple>(t));
}
template<int g_count, int f_count, int v_count>
static __forceinline std::tuple<> iterate(PPUThread& CPU)
__forceinline std::tuple<> iterate(PPUThread& CPU)
{
// terminator
return std::tuple<>();
}
template<int g_count, int f_count, int v_count, typename T, typename... A>
static __forceinline std::tuple<T, A...> iterate(PPUThread& CPU)
__forceinline std::tuple<T, A...> iterate(PPUThread& CPU)
{
static_assert(!std::is_pointer<T>::value, "Invalid function argument type (pointer)");
static_assert(!std::is_reference<T>::value, "Invalid function argument type (reference)");
@ -153,6 +153,16 @@ namespace detail
return std::tuple_cat(std::tuple<T>(bind_arg<T, t, g, f, v>::func(CPU)), iterate<g, f, v, A...>(CPU));
}
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... T>
class func_binder;
@ -209,13 +219,7 @@ namespace detail
virtual void operator()(PPUThread& CPU)
{
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
const bool is_float = std::is_floating_point<RT>::value;
const bool is_vector = std::is_same<RT, u128>::value;
const bind_arg_type t = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
bind_result<RT, t>::func(CPU, call<RT>(m_call, iterate<0, 0, 0, T...>(CPU)));
bind_result<RT, result_type<RT>::value>::func(CPU, call<RT>(m_call, iterate<0, 0, 0, T...>(CPU)));
}
};
@ -234,13 +238,7 @@ namespace detail
virtual void operator()(PPUThread& CPU)
{
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
const bool is_float = std::is_floating_point<RT>::value;
const bool is_vector = std::is_same<RT, u128>::value;
const bind_arg_type t = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
bind_result<RT, t>::func(CPU, call<RT>(m_call, std::tuple_cat(std::tuple<PPUThread&>(CPU), iterate<0, 0, 0, T...>(CPU))));
bind_result<RT, result_type<RT>::value>::func(CPU, call<RT>(m_call, std::tuple_cat(std::tuple<PPUThread&>(CPU), iterate<0, 0, 0, T...>(CPU))));
}
};
}
@ -248,5 +246,5 @@ namespace detail
template<typename RT, typename... T>
func_caller* bind_func(RT(*call)(T...))
{
return new detail::func_binder<RT, T...>(call);
return new ppu_func_detail::func_binder<RT, T...>(call);
}

View File

@ -39,10 +39,9 @@ struct FsRingBufferConfig
} fs_config;
s32 cellFsOpen(vm::ptr<const char> path, s32 flags, vm::ptr<be_t<u32>> fd, vm::ptr<u32> arg, u64 size)
s32 cellFsOpen(vm::ptr<const char> path, s32 flags, vm::ptr<be_t<u32>> fd, vm::ptr<const void> arg, u64 size)
{
sys_fs->Log("cellFsOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx)",
path.get_ptr(), flags, fd.addr(), arg.addr(), size);
sys_fs->Log("cellFsOpen(path=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx)", path, flags, fd, arg, size);
const std::string _path = path.get_ptr();
@ -97,13 +96,13 @@ s32 cellFsOpen(vm::ptr<const char> path, s32 flags, vm::ptr<be_t<u32>> fd, vm::p
if (_oflags != 0)
{
sys_fs->Error("\"%s\" has unknown flags! flags: 0x%08x", path.get_ptr(), flags);
sys_fs->Error("cellFsOpen(): '%s' has unknown flags! flags: 0x%08x", path.get_ptr(), flags);
return CELL_EINVAL;
}
if (!Emu.GetVFS().ExistsFile(_path))
{
sys_fs->Error("\"%s\" not found! flags: 0x%08x", path.get_ptr(), flags);
sys_fs->Error("cellFsOpen(): '%s' not found! flags: 0x%08x", path.get_ptr(), flags);
return CELL_ENOENT;
}
@ -111,21 +110,20 @@ s32 cellFsOpen(vm::ptr<const char> path, s32 flags, vm::ptr<be_t<u32>> fd, vm::p
if (!stream || !stream->IsOpened())
{
sys_fs->Error("\"%s\" not found! flags: 0x%08x", path.get_ptr(), flags);
sys_fs->Error("cellFsOpen(): '%s' not found! flags: 0x%08x", path.get_ptr(), flags);
return CELL_ENOENT;
}
u32 id = sys_fs->GetNewId(stream, TYPE_FS_FILE);
*fd = id;
sys_fs->Notice("\"%s\" opened: fd = %d", path.get_ptr(), id);
sys_fs->Notice("cellFsOpen(): '%s' opened, id -> 0x%x", path.get_ptr(), id);
return CELL_OK;
}
s32 cellFsRead(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<be_t<u64>> nread)
{
sys_fs->Log("cellFsRead(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nread_addr=0x%x)",
fd, buf.addr(), nbytes, nread.addr());
sys_fs->Log("cellFsRead(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -145,8 +143,7 @@ s32 cellFsRead(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<be_t<u64>> nread)
s32 cellFsWrite(u32 fd, vm::ptr<const void> buf, u64 nbytes, vm::ptr<u64> nwrite)
{
sys_fs->Log("cellFsWrite(fd=%d, buf_addr=0x%x, nbytes=0x%llx, nwrite_addr=0x%x)",
fd, buf.addr(), nbytes, nwrite.addr());
sys_fs->Log("cellFsWrite(fd=0x%x, buf=0x%x, nbytes=0x%llx, nwrite=0x%x)", fd, buf, nbytes, nwrite);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH;
@ -164,7 +161,7 @@ s32 cellFsWrite(u32 fd, vm::ptr<const void> buf, u64 nbytes, vm::ptr<u64> nwrite
s32 cellFsClose(u32 fd)
{
sys_fs->Warning("cellFsClose(fd=%d)", fd);
sys_fs->Warning("cellFsClose(fd=0x%x)", fd);
if (!Emu.GetIdManager().RemoveID(fd))
return CELL_ESRCH;
@ -174,7 +171,7 @@ s32 cellFsClose(u32 fd)
s32 cellFsOpendir(vm::ptr<const char> path, vm::ptr<u32> fd)
{
sys_fs->Warning("cellFsOpendir(path=\"%s\", fd_addr=0x%x)", path.get_ptr(), fd.addr());
sys_fs->Warning("cellFsOpendir(path=0x%x, fd=0x%x)", path, fd);
std::shared_ptr<vfsDirBase> dir(Emu.GetVFS().OpenDir(path.get_ptr()));
if (!dir || !dir->IsOpened())
@ -188,7 +185,7 @@ s32 cellFsOpendir(vm::ptr<const char> path, vm::ptr<u32> fd)
s32 cellFsReaddir(u32 fd, vm::ptr<CellFsDirent> dir, vm::ptr<u64> nread)
{
sys_fs->Warning("cellFsReaddir(fd=%d, dir_addr=0x%x, nread_addr=0x%x)", fd, dir.addr(), nread.addr());
sys_fs->Warning("cellFsReaddir(fd=0x%x, dir=0x%x, nread=0x%x)", fd, dir, nread);
std::shared_ptr<vfsDirBase> directory;
if (!sys_fs->CheckId(fd, directory))
@ -212,7 +209,7 @@ s32 cellFsReaddir(u32 fd, vm::ptr<CellFsDirent> dir, vm::ptr<u64> nread)
s32 cellFsClosedir(u32 fd)
{
sys_fs->Warning("cellFsClosedir(fd=%d)", fd);
sys_fs->Warning("cellFsClosedir(fd=0x%x)", fd);
if (!Emu.GetIdManager().RemoveID(fd))
return CELL_ESRCH;
@ -222,7 +219,7 @@ s32 cellFsClosedir(u32 fd)
s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
{
sys_fs->Warning("cellFsStat(path=\"%s\", sb_addr=0x%x)", path.get_ptr(), sb.addr());
sys_fs->Warning("cellFsStat(path=0x%x, sb=0x%x)", path, sb);
const std::string _path = path.get_ptr();
@ -242,7 +239,7 @@ s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
if (int result = stat(real_path.c_str(), &buf))
{
sys_fs->Error("stat('%s') failed -> 0x%x", real_path.c_str(), result);
sys_fs->Error("cellFsStat(): stat('%s') failed -> 0x%x", real_path.c_str(), result);
}
else
{
@ -261,7 +258,7 @@ s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH;
if (sb->st_mode == mode)
sys_fs->Error("Mode is the same. Report this to a RPCS3 developer! (%d)", mode);
sys_fs->Error("cellFsStat(): mode is the same (0x%x)", mode);
sb->st_uid = uid;
sb->st_gid = gid;
@ -290,15 +287,15 @@ s32 cellFsStat(vm::ptr<const char> path, vm::ptr<CellFsStat> sb)
}
if (sb->st_size == size && size != 0)
sys_fs->Error("Size is the same. Report this to a RPCS3 developer! (%d)", size);
sys_fs->Error("cellFsStat(): size is the same (0x%x)", size);
sys_fs->Warning("cellFsStat: \"%s\" not found.", path.get_ptr());
sys_fs->Warning("cellFsStat(): '%s' not found", path.get_ptr());
return CELL_ENOENT;
}
s32 cellFsFstat(u32 fd, vm::ptr<CellFsStat> sb)
{
sys_fs->Warning("cellFsFstat(fd=%d, sb_addr=0x%x)", fd, sb.addr());
sys_fs->Warning("cellFsFstat(fd=0x%x, sb=0x%x)", fd, sb);
IDType type;
std::shared_ptr<vfsStream> file;
@ -324,7 +321,7 @@ s32 cellFsFstat(u32 fd, vm::ptr<CellFsStat> sb)
s32 cellFsMkdir(vm::ptr<const char> path, u32 mode)
{
sys_fs->Warning("cellFsMkdir(path=\"%s\", mode=0x%x)", path.get_ptr(), mode);
sys_fs->Warning("cellFsMkdir(path=0x%x, mode=0x%x)", path, mode);
const std::string _path = path.get_ptr();
@ -334,12 +331,13 @@ s32 cellFsMkdir(vm::ptr<const char> path, u32 mode)
if (!Emu.GetVFS().CreateDir(_path))
return CELL_EBUSY;
sys_fs->Notice("cellFsMkdir(): directory '%s' created", path.get_ptr());
return CELL_OK;
}
s32 cellFsRename(vm::ptr<const char> from, vm::ptr<const char> to)
{
sys_fs->Warning("cellFsRename(from='%s', to='%s')", from.get_ptr(), to.get_ptr());
sys_fs->Warning("cellFsRename(from=0x%x, to=0x%x)", from, to);
std::string _from = from.get_ptr();
std::string _to = to.get_ptr();
@ -351,6 +349,7 @@ s32 cellFsRename(vm::ptr<const char> from, vm::ptr<const char> to)
if(!dir.Rename(_from, _to))
return CELL_EBUSY;
sys_fs->Notice("cellFsRename(): directory '%s' renamed to '%s'", from.get_ptr(), to.get_ptr());
return CELL_OK;
}
}
@ -363,6 +362,7 @@ s32 cellFsRename(vm::ptr<const char> from, vm::ptr<const char> to)
if(!f.Rename(_from, _to))
return CELL_EBUSY;
sys_fs->Notice("cellFsRename(): file '%s' renamed to '%s'", from.get_ptr(), to.get_ptr());
return CELL_OK;
}
}
@ -371,7 +371,7 @@ s32 cellFsRename(vm::ptr<const char> from, vm::ptr<const char> to)
}
s32 cellFsChmod(vm::ptr<const char> path, u32 mode)
{
sys_fs->Todo("cellFsChmod(path=\"%s\", mode=0x%x)", path.get_ptr(), mode);
sys_fs->Todo("cellFsChmod(path=0x%x, mode=0x%x)", path, mode);
// TODO:
@ -389,7 +389,7 @@ s32 cellFsFsync(u32 fd)
s32 cellFsRmdir(vm::ptr<const char> path)
{
sys_fs->Warning("cellFsRmdir(path=\"%s\")", path.get_ptr());
sys_fs->Warning("cellFsRmdir(path=0x%x)", path.get_ptr());
std::string _path = path.get_ptr();
@ -400,12 +400,13 @@ s32 cellFsRmdir(vm::ptr<const char> path)
if (!d.Remove(_path))
return CELL_EBUSY;
sys_fs->Notice("cellFsRmdir(): directory '%s' removed", path.get_ptr());
return CELL_OK;
}
s32 cellFsUnlink(vm::ptr<const char> path)
{
sys_fs->Warning("cellFsUnlink(path=\"%s\")", path.get_ptr());
sys_fs->Warning("cellFsUnlink(path=0x%x)", path);
std::string _path = path.get_ptr();
@ -418,12 +419,13 @@ s32 cellFsUnlink(vm::ptr<const char> path)
if (!Emu.GetVFS().RemoveFile(_path))
return CELL_EACCES;
sys_fs->Notice("cellFsUnlink(): file '%s' removed", path.get_ptr());
return CELL_OK;
}
s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr<be_t<u64>> pos)
{
sys_fs->Log("cellFsLseek(fd=%d, offset=0x%llx, whence=0x%x, pos_addr=0x%x)", fd, offset, whence, pos.addr());
sys_fs->Log("cellFsLseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=0x%x)", fd, offset, whence, pos);
vfsSeekMode seek_mode;
switch(whence)
@ -432,7 +434,7 @@ s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr<be_t<u64>> pos)
case CELL_SEEK_CUR: seek_mode = vfsSeekCur; break;
case CELL_SEEK_END: seek_mode = vfsSeekEnd; break;
default:
sys_fs->Error(fd, "Unknown seek whence! (0x%x)", whence);
sys_fs->Error("cellFsLseek(fd=0x%x): Unknown seek whence! (0x%x)", fd, whence);
return CELL_EINVAL;
}
@ -447,7 +449,7 @@ s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr<be_t<u64>> pos)
s32 cellFsFtruncate(u32 fd, u64 size)
{
sys_fs->Warning("cellFsFtruncate(fd=%d, size=%lld)", fd, size);
sys_fs->Warning("cellFsFtruncate(fd=0x%x, size=0x%llx)", fd, size);
IDType type;
std::shared_ptr<vfsStream> file;
@ -476,12 +478,12 @@ s32 cellFsFtruncate(u32 fd, u64 size)
s32 cellFsTruncate(vm::ptr<const char> path, u64 size)
{
sys_fs->Warning("cellFsTruncate(path=\"%s\", size=%lld)", path.get_ptr(), size);
sys_fs->Warning("cellFsTruncate(path=0x%x, size=0x%llx)", path, size);
vfsFile f(path.get_ptr(), vfsReadWrite);
if (!f.IsOpened())
{
sys_fs->Warning("cellFsTruncate: \"%s\" not found.", path.get_ptr());
sys_fs->Warning("cellFsTruncate(): '%s' not found", path.get_ptr());
return CELL_ENOENT;
}
u64 initialSize = f.GetSize();
@ -506,8 +508,7 @@ s32 cellFsTruncate(vm::ptr<const char> path, u64 size)
s32 cellFsFGetBlockSize(u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_size)
{
sys_fs->Warning("cellFsFGetBlockSize(fd=%d, sector_size_addr=0x%x, block_size_addr=0x%x)",
fd, sector_size.addr(), block_size.addr());
sys_fs->Warning("cellFsFGetBlockSize(fd=0x%x, sector_size=0x%x, block_size=0x%x)", fd, sector_size, block_size);
LV2_LOCK(0);
@ -523,8 +524,7 @@ s32 cellFsFGetBlockSize(u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_siz
s32 cellFsGetBlockSize(vm::ptr<const char> path, vm::ptr<u64> sector_size, vm::ptr<u64> block_size)
{
sys_fs->Warning("cellFsGetBlockSize(file='%s', sector_size_addr=0x%x, block_size_addr=0x%x)",
path.get_ptr(), sector_size.addr(), block_size.addr());
sys_fs->Warning("cellFsGetBlockSize(path=0x%x, sector_size=0x%x, block_size=0x%x)", path, sector_size, block_size);
*sector_size = 4096; // ?
*block_size = 4096; // ?
@ -534,8 +534,7 @@ s32 cellFsGetBlockSize(vm::ptr<const char> path, vm::ptr<u64> sector_size, vm::p
s32 cellFsGetFreeSize(vm::ptr<const char> path, vm::ptr<u32> block_size, vm::ptr<u64> block_count)
{
sys_fs->Warning("cellFsGetFreeSize(path=\"%s\", block_size_addr=0x%x, block_count_addr=0x%x)",
path.get_ptr(), block_size.addr(), block_count.addr());
sys_fs->Warning("cellFsGetFreeSize(path=0x%x, block_size=0x%x, block_count=0x%x)", path, block_size, block_count);
// TODO: Get real values. Currently, it always returns 40 GB of free space divided in 4 KB blocks
*block_size = 4096; // ?
@ -546,8 +545,7 @@ s32 cellFsGetFreeSize(vm::ptr<const char> path, vm::ptr<u32> block_size, vm::ptr
s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr<CellFsDirectoryEntry> entries, u32 entries_size, vm::ptr<u32> data_count)
{
sys_fs->Warning("cellFsGetDirectoryEntries(fd=%d, entries_addr=0x%x, entries_size=0x%x, data_count_addr=0x%x)",
fd, entries.addr(), entries_size, data_count.addr());
sys_fs->Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=0x%x, entries_size=0x%x, data_count=0x%x)", fd, entries, entries_size, data_count);
std::shared_ptr<vfsDirBase> directory;
if (!sys_fs->CheckId(fd, directory))
@ -583,7 +581,7 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr<CellFsDirectoryEntry> entries, u32
s32 cellFsStReadInit(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
{
sys_fs->Warning("cellFsStReadInit(fd=%d, ringbuf_addr=0x%x)", fd, ringbuf.addr());
sys_fs->Warning("cellFsStReadInit(fd=0x%x, ringbuf=0x%x)", fd, ringbuf);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -608,7 +606,7 @@ s32 cellFsStReadInit(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
s32 cellFsStReadFinish(u32 fd)
{
sys_fs->Warning("cellFsStReadFinish(fd=%d)", fd);
sys_fs->Warning("cellFsStReadFinish(fd=0x%x)", fd);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -622,7 +620,7 @@ s32 cellFsStReadFinish(u32 fd)
s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
{
sys_fs->Warning("cellFsStReadGetRingBuf(fd=%d, ringbuf_addr=0x%x)", fd, ringbuf.addr());
sys_fs->Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=0x%x)", fd, ringbuf);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -630,14 +628,14 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
*ringbuf = fs_config.m_ring_buffer;
sys_fs->Warning("*** fs stream config: block_size=0x%llx, copy=%d, ringbuf_size=0x%llx, transfer_rate=0x%llx",
(u64)ringbuf->block_size, (u32)ringbuf->copy, (u64)ringbuf->ringbuf_size, (u64)ringbuf->transfer_rate);
sys_fs->Warning("*** fs stream config: block_size=0x%llx, copy=0x%x, ringbuf_size=0x%llx, transfer_rate=0x%llx",
ringbuf->block_size, ringbuf->copy, ringbuf->ringbuf_size, ringbuf->transfer_rate);
return CELL_OK;
}
s32 cellFsStReadGetStatus(u32 fd, vm::ptr<u64> status)
{
sys_fs->Warning("cellFsStReadGetRingBuf(fd=%d, status_addr=0x%x)", fd, status.addr());
sys_fs->Warning("cellFsStReadGetRingBuf(fd=0x%x, status=0x%x)", fd, status);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -650,7 +648,7 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr<u64> status)
s32 cellFsStReadGetRegid(u32 fd, vm::ptr<u64> regid)
{
sys_fs->Warning("cellFsStReadGetRingBuf(fd=%d, regid_addr=0x%x)", fd, regid.addr());
sys_fs->Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=0x%x)", fd, regid);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -663,7 +661,7 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr<u64> regid)
s32 cellFsStReadStart(u32 fd, u64 offset, u64 size)
{
sys_fs->Todo("cellFsStReadStart(fd=%d, offset=0x%llx, size=0x%llx)", fd, offset, size);
sys_fs->Todo("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -677,7 +675,7 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size)
s32 cellFsStReadStop(u32 fd)
{
sys_fs->Warning("cellFsStReadStop(fd=%d)", fd);
sys_fs->Warning("cellFsStReadStop(fd=0x%x)", fd);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -688,9 +686,9 @@ s32 cellFsStReadStop(u32 fd)
return CELL_OK;
}
s32 cellFsStRead(u32 fd, u32 buf_addr, u64 size, vm::ptr<u64> rsize)
s32 cellFsStRead(u32 fd, vm::ptr<u8> buf, u64 size, vm::ptr<u64> rsize)
{
sys_fs->Warning("cellFsStRead(fd=%d, buf_addr=0x%x, size=0x%llx, rsize_addr=0x%x)", fd, buf_addr, size, rsize.addr());
sys_fs->Warning("cellFsStRead(fd=0x%x, buf=0x%x, size=0x%llx, rsize=0x%x)", fd, buf, size, rsize);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -702,14 +700,14 @@ s32 cellFsStRead(u32 fd, u32 buf_addr, u64 size, vm::ptr<u64> rsize)
if (file->Eof())
return CELL_FS_ERANGE;
*rsize = file->Read(vm::get_ptr<void>(buf_addr), size);
*rsize = file->Read(buf.get_ptr(), size);
return CELL_OK;
}
s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<u32> addr, vm::ptr<u64> size)
s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<vm::ptr<u8>> addr, vm::ptr<u64> size)
{
sys_fs->Todo("cellFsStReadGetCurrentAddr(fd=%d, addr_addr=0x%x, size_addr=0x%x)", fd, addr.addr(), size.addr());
sys_fs->Todo("cellFsStReadGetCurrentAddr(fd=0x%x, addr=0x%x, size=0x%x)", fd, addr, size);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -718,9 +716,9 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<u32> addr, vm::ptr<u64> size)
return CELL_OK;
}
s32 cellFsStReadPutCurrentAddr(u32 fd, u32 addr_addr, u64 size)
s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr<u8> addr, u64 size)
{
sys_fs->Todo("cellFsStReadPutCurrentAddr(fd=%d, addr_addr=0x%x, size=0x%llx)", fd, addr_addr, size);
sys_fs->Todo("cellFsStReadPutCurrentAddr(fd=0x%x, addr=0x%x, size=0x%llx)", fd, addr, size);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -731,7 +729,7 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, u32 addr_addr, u64 size)
s32 cellFsStReadWait(u32 fd, u64 size)
{
sys_fs->Todo("cellFsStReadWait(fd=%d, size=0x%llx)", fd, size);
sys_fs->Todo("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -742,7 +740,7 @@ s32 cellFsStReadWait(u32 fd, u64 size)
s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr<void (*)(int xfd, u64 xsize)> func)
{
sys_fs->Todo("cellFsStReadWaitCallback(fd=%d, size=0x%llx, func_addr=0x%x)", fd, size, func.addr());
sys_fs->Todo("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=0x%x)", fd, size, func);
std::shared_ptr<vfsStream> file;
if (!sys_fs->CheckId(fd, file))
@ -851,10 +849,9 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil
return CELL_OK;
}
int cellFsSdataOpen(vm::ptr<const char> path, int flags, vm::ptr<be_t<u32>> fd, vm::ptr<u32> arg, u64 size)
s32 cellFsSdataOpen(vm::ptr<const char> path, s32 flags, vm::ptr<be_t<u32>> fd, vm::ptr<const void> arg, u64 size)
{
sys_fs->Warning("cellFsSdataOpen(path=\"%s\", flags=0x%x, fd_addr=0x%x, arg_addr=0x%x, size=0x%llx) -> cellFsOpen()",
path.get_ptr(), flags, fd.addr(), arg.addr(), size);
sys_fs->Warning("cellFsSdataOpen(path=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx) -> cellFsOpen()", path, flags, fd, arg, size);
/*if (flags != CELL_O_RDONLY)
return CELL_EINVAL;
@ -876,18 +873,17 @@ int cellFsSdataOpen(vm::ptr<const char> path, int flags, vm::ptr<be_t<u32>> fd,
return cellFsOpen(path, flags, fd, arg, size);
}
int cellFsSdataOpenByFd(int mself_fd, int flags, vm::ptr<u32> sdata_fd, u64 offset, vm::ptr<u32> arg, u64 size)
s32 cellFsSdataOpenByFd(u32 mself_fd, s32 flags, vm::ptr<u32> sdata_fd, u64 offset, vm::ptr<const void> arg, u64 size)
{
sys_fs->Todo("cellFsSdataOpenByFd(mself_fd=0x%x, flags=0x%x, sdata_fd_addr=0x%x, offset=0x%llx, arg_addr=0x%x, size=0x%llx) -> cellFsOpen()",
mself_fd, flags, sdata_fd.addr(), offset, arg.addr(), size);
sys_fs->Todo("cellFsSdataOpenByFd(mself_fd=0x%x, flags=0x%x, sdata_fd=0x%x, offset=0x%llx, arg=0x%x, size=0x%llx)", mself_fd, flags, sdata_fd, offset, arg, size);
// TODO:
return CELL_OK;
}
std::atomic<u32> g_FsAioReadID(0);
std::atomic<u32> g_FsAioReadCur(0);
std::atomic<s32> g_FsAioReadID(0);
std::atomic<s32> g_FsAioReadCur(0);
bool aio_init = false;
void fsAioRead(u32 fd, vm::ptr<CellFsAio> aio, int xid, vm::ptr<void(*)(vm::ptr<CellFsAio> xaio, int error, int xid, u64 size)> func)
@ -930,7 +926,7 @@ void fsAioRead(u32 fd, vm::ptr<CellFsAio> aio, int xid, vm::ptr<void(*)(vm::ptr<
file.Seek(old_pos);
sys_fs->Log("*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%llx, error=0x%x, res=0x%llx, xid=0x%x)",
sys_fs->Log("*** fsAioRead(fd=%d, offset=0x%llx, buf=0x%x, size=0x%llx, error=0x%x, res=0x%llx, xid=0x%x)",
fd, aio->offset, aio->buf, aio->size, error, res, xid);
}
@ -945,7 +941,7 @@ void fsAioRead(u32 fd, vm::ptr<CellFsAio> aio, int xid, vm::ptr<void(*)(vm::ptr<
g_FsAioReadCur++;
}
int cellFsAioRead(vm::ptr<CellFsAio> aio, vm::ptr<u32> id, vm::ptr<void(*)(vm::ptr<CellFsAio> xaio, int error, int xid, u64 size)> func)
s32 cellFsAioRead(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, vm::ptr<void(*)(vm::ptr<CellFsAio> xaio, s32 error, s32 xid, u64 size)> func)
{
sys_fs->Warning("cellFsAioRead(aio=0x%x, id=0x%x, func=0x%x)", aio, id, func);
@ -963,42 +959,41 @@ int cellFsAioRead(vm::ptr<CellFsAio> aio, vm::ptr<u32> id, vm::ptr<void(*)(vm::p
}
//get a unique id for the callback (may be used by cellFsAioCancel)
const u32 xid = g_FsAioReadID++;
const s32 xid = g_FsAioReadID++;
*id = xid;
thread_t t("CellFsAio Reading Thread", std::bind(fsAioRead, fd, aio, xid, func));
return CELL_OK;
}
int cellFsAioWrite(vm::ptr<CellFsAio> aio, vm::ptr<u32> aio_id, vm::ptr<void(*)(vm::ptr<CellFsAio> xaio, int error, int xid, u64 size)> func)
s32 cellFsAioWrite(vm::ptr<CellFsAio> aio, vm::ptr<s32> id, vm::ptr<void(*)(vm::ptr<CellFsAio> xaio, s32 error, s32 xid, u64 size)> func)
{
sys_fs->Todo("cellFsAioWrite(aio_addr=0x%x, id_addr=0x%x, func_addr=0x%x)", aio.addr(), aio_id.addr(), func.addr());
sys_fs->Todo("cellFsAioWrite(aio=0x%x, id=0x%x, func=0x%x)", aio, id, func);
// TODO:
return CELL_OK;
}
int cellFsAioInit(vm::ptr<const char> mount_point)
s32 cellFsAioInit(vm::ptr<const char> mount_point)
{
sys_fs->Warning("cellFsAioInit(mount_point_addr=0x%x (%s))", mount_point.addr(), mount_point.get_ptr());
sys_fs->Warning("cellFsAioInit(mount_point=0x%x)", mount_point);
aio_init = true;
return CELL_OK;
}
int cellFsAioFinish(vm::ptr<const char> mount_point)
s32 cellFsAioFinish(vm::ptr<const char> mount_point)
{
sys_fs->Warning("cellFsAioFinish(mount_point_addr=0x%x (%s))", mount_point.addr(), mount_point.get_ptr());
sys_fs->Warning("cellFsAioFinish(mount_point=0x%x)", mount_point);
aio_init = false;
//aio_init = false;
return CELL_OK;
}
int cellFsReadWithOffset(PPUThread& CPU, u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size, vm::ptr<be_t<u64>> nread)
s32 cellFsReadWithOffset(PPUThread& CPU, u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size, vm::ptr<be_t<u64>> nread)
{
sys_fs->Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf_addr=0x%x, buffer_size=%lld nread=0x%llx)",
fd, offset, buf.addr(), buffer_size, nread.addr());
sys_fs->Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf=0x%x, buffer_size=%lld, nread=0x%llx)", fd, offset, buf, buffer_size, nread);
int ret;
vm::stackvar<be_t<u64>> oldPos(CPU), newPos(CPU);

View File

@ -128,7 +128,7 @@ struct CellFsRingBuffer
};
// SysCalls
s32 cellFsOpen(vm::ptr<const char> path, s32 flags, vm::ptr<be_t<u32>> fd, vm::ptr<u32> arg, u64 size);
s32 cellFsOpen(vm::ptr<const char> path, s32 flags, vm::ptr<be_t<u32>> fd, vm::ptr<const void> arg, u64 size);
s32 cellFsRead(u32 fd, vm::ptr<void> buf, u64 nbytes, vm::ptr<be_t<u64>> nread);
s32 cellFsWrite(u32 fd, vm::ptr<const void> buf, u64 nbytes, vm::ptr<u64> nwrite);
s32 cellFsClose(u32 fd);
@ -150,15 +150,5 @@ s32 cellFsFGetBlockSize(u32 fd, vm::ptr<u64> sector_size, vm::ptr<u64> block_siz
s32 cellFsGetBlockSize(vm::ptr<const char> path, vm::ptr<u64> sector_size, vm::ptr<u64> block_size);
s32 cellFsGetFreeSize(vm::ptr<const char> path, vm::ptr<u32> block_size, vm::ptr<u64> block_count);
s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr<CellFsDirectoryEntry> entries, u32 entries_size, vm::ptr<u32> data_count);
s32 cellFsStReadInit(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf);
s32 cellFsStReadFinish(u32 fd);
s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf);
s32 cellFsStReadGetStatus(u32 fd, vm::ptr<u64> status);
s32 cellFsStReadGetRegid(u32 fd, vm::ptr<u64> regid);
s32 cellFsStReadStart(u32 fd, u64 offset, u64 size);
s32 cellFsStReadStop(u32 fd);
s32 cellFsStRead(u32 fd, u32 buf_addr, u64 size, vm::ptr<u64> rsize);
s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<u32> addr_addr, vm::ptr<u64> size);
s32 cellFsStReadPutCurrentAddr(u32 fd, u32 addr_addr, u64 size);
s32 cellFsStReadWait(u32 fd, u64 size);
s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr<void (*)(int xfd, u64 xsize)> func);
// no need to add every function here

View File

@ -14,10 +14,12 @@ SysCallBase sys_lwcond("sys_lwcond");
s32 lwcond_create(sys_lwcond_t& lwcond, sys_lwmutex_t& lwmutex, u64 name_u64)
{
std::shared_ptr<Lwcond> lw(new Lwcond(name_u64, Memory.RealToVirtualAddr(&lwcond)));
const u32 addr = vm::get_addr(&lwmutex);
std::shared_ptr<Lwcond> lw(new Lwcond(name_u64, addr));
const u32 id = sys_lwcond.GetNewId(lw, TYPE_LWCOND);
const u32 addr = Memory.RealToVirtualAddr(&lwmutex);
lw->queue.set_full_name(fmt::Format("Lwcond(%d, addr=0x%x)", id, lw->addr));
lwcond.lwmutex.set(addr);
lwcond.lwcond_queue = id;
@ -65,7 +67,7 @@ s32 sys_lwcond_signal(vm::ptr<sys_lwcond_t> lwcond)
return CELL_ESRCH;
}
auto mutex = vm::ptr<sys_lwmutex_t>::make(lwcond->lwmutex.addr());
auto mutex = lwcond->lwmutex.to_le();
if (u32 target = lw->queue.signal(mutex->attribute))
{
@ -89,7 +91,7 @@ s32 sys_lwcond_signal_all(vm::ptr<sys_lwcond_t> lwcond)
return CELL_ESRCH;
}
auto mutex = vm::ptr<sys_lwmutex_t>::make(lwcond->lwmutex.addr());
auto mutex = lwcond->lwmutex.to_le();
while (u32 target = lw->queue.signal(mutex->attribute))
{
@ -138,9 +140,9 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
return CELL_ESRCH;
}
auto mutex = vm::ptr<sys_lwmutex_t>::make(lwcond->lwmutex.addr());
auto mutex = lwcond->lwmutex.to_le();
u32 tid_le = CPU.GetId();
be_t<u32> tid = be_t<u32>::make(tid_le);
auto tid = be_t<u32>::make(tid_le);
std::shared_ptr<sleep_queue_t> sq;
if (!Emu.GetIdManager().GetIDData((u32)mutex->sleep_queue, sq))
@ -160,7 +162,7 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
auto old_recursive = mutex->recursive_count.read_relaxed();
mutex->recursive_count.exchange(be_t<u32>::make(0));
be_t<u32> target = be_t<u32>::make(sq->signal(mutex->attribute));
auto target = be_t<u32>::make(sq->signal(mutex->attribute));
if (!mutex->owner.compare_and_swap_test(tid, target))
{
assert(!"sys_lwcond_wait(): mutex unlocking failed");

View File

@ -22,7 +22,7 @@ s32 lwmutex_create(sys_lwmutex_t& lwmutex, u32 protocol, u32 recursive, u64 name
lwmutex.recursive_count.write_relaxed(be_t<u32>::make(0));
u32 sq_id = sys_lwmutex.GetNewId(sq, TYPE_LWMUTEX);
lwmutex.sleep_queue = sq_id;
sq->set_full_name(fmt::Format("Lwmutex(%d, addr=0x%x)", sq_id, Memory.RealToVirtualAddr(&lwmutex)));
sq->set_full_name(fmt::Format("Lwmutex(%d, addr=0x%x)", sq_id, vm::get_addr(&lwmutex)));
// passing be_t<u32> (test)
sys_lwmutex.Notice("*** lwmutex created [%s] (attribute=0x%x): sq_id = %d", std::string((const char*)&name_u64, 8).c_str(), lwmutex.attribute, sq_id);

View File

@ -214,8 +214,7 @@ void sys_ppu_thread_once(PPUThread& CPU, vm::ptr<atomic_t<u32>> once_ctrl, vm::p
{
sys_ppu_thread.Warning("sys_ppu_thread_once(once_ctrl_addr=0x%x, init_addr=0x%x)", once_ctrl.addr(), init.addr());
be_t<u32> cmp = be_t<u32>::make(SYS_PPU_THREAD_ONCE_INIT);
if (once_ctrl->compare_and_swap(cmp, be_t<u32>::make(SYS_PPU_THREAD_DONE_INIT)) == cmp)
if (once_ctrl->compare_and_swap_test(be_t<u32>::make(SYS_PPU_THREAD_ONCE_INIT), be_t<u32>::make(SYS_PPU_THREAD_DONE_INIT)))
{
init(CPU);
}