mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
commit
2032b15acf
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define IS_LE_MACHINE
|
||||
|
||||
union _CRT_ALIGN(16) u128
|
||||
{
|
||||
u64 _u64[2];
|
||||
@ -136,16 +138,28 @@ union _CRT_ALIGN(16) u128
|
||||
}
|
||||
};
|
||||
|
||||
// Index 0 returns the MSB and index 127 returns the LSB
|
||||
bit_element operator [] (u32 index)
|
||||
{
|
||||
assert(index < 128);
|
||||
return bit_element(data[index / 64], 1ull << (index % 64));
|
||||
|
||||
#ifdef IS_LE_MACHINE
|
||||
return bit_element(data[1 - (index >> 6)], 0x8000000000000000ull >> (index & 0x3F));
|
||||
#else
|
||||
return bit_element(data[index >> 6], 0x8000000000000000ull >> (index & 0x3F));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Index 0 returns the MSB and index 127 returns the LSB
|
||||
const bool operator [] (u32 index) const
|
||||
{
|
||||
assert(index < 128);
|
||||
return (data[index / 64] & (1ull << (index % 64))) != 0;
|
||||
|
||||
#ifdef IS_LE_MACHINE
|
||||
return (data[1 - (index >> 6)] & (0x8000000000000000ull >> (index & 0x3F))) != 0;
|
||||
#else
|
||||
return (data[index >> 6] & (0x8000000000000000ull >> (index & 0x3F))) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
} _bit;
|
||||
@ -509,8 +523,6 @@ struct be_storage_t<T, 16>
|
||||
typedef u128 type;
|
||||
};
|
||||
|
||||
#define IS_LE_MACHINE
|
||||
|
||||
template<typename T, typename T2 = T>
|
||||
class be_t
|
||||
{
|
||||
|
@ -35,6 +35,14 @@ enum
|
||||
MFC_GETLLAR_SUCCESS = 4,
|
||||
};
|
||||
|
||||
// MFC Write Tag Status Update Request Channel (ch23) operations
|
||||
enum
|
||||
{
|
||||
MFC_TAG_UPDATE_IMMEDIATE = 0,
|
||||
MFC_TAG_UPDATE_ANY = 1,
|
||||
MFC_TAG_UPDATE_ALL = 2,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MFC_SPU_TO_PPU_MAILBOX_STATUS_MASK = 0x000000FF,
|
||||
|
@ -1316,10 +1316,7 @@ private:
|
||||
|
||||
void FSCRRD(u32 rt)
|
||||
{
|
||||
CPU.GPR[rt]._u32[3] = CPU.FPSCR._u32[3];
|
||||
CPU.GPR[rt]._u32[2] = CPU.FPSCR._u32[2];
|
||||
CPU.GPR[rt]._u32[1] = CPU.FPSCR._u32[1];
|
||||
CPU.GPR[rt]._u32[0] = CPU.FPSCR._u32[0];
|
||||
CPU.FPSCR.Read(CPU.GPR[rt]);
|
||||
}
|
||||
void FESD(u32 rt, u32 ra)
|
||||
{
|
||||
@ -1373,10 +1370,7 @@ private:
|
||||
}
|
||||
void FSCRWR(u32 rt, u32 ra)
|
||||
{
|
||||
CPU.FPSCR._u32[3] = CPU.GPR[ra]._u32[3] & 0x00000F07;
|
||||
CPU.FPSCR._u32[2] = CPU.GPR[ra]._u32[2] & 0x00003F07;
|
||||
CPU.FPSCR._u32[1] = CPU.GPR[ra]._u32[1] & 0x00003F07;
|
||||
CPU.FPSCR._u32[0] = CPU.GPR[ra]._u32[0] & 0x00000F07;
|
||||
CPU.FPSCR.Write(CPU.GPR[ra]);
|
||||
}
|
||||
void DFTSV(u32 rt, u32 ra, s32 i7)
|
||||
{
|
||||
|
@ -1003,7 +1003,14 @@ void SPUThread::StopAndSignal(u32 code)
|
||||
|
||||
case 0x003:
|
||||
{
|
||||
GPR[3]._u64[1] = m_code3_func(*this);
|
||||
auto iter = m_addr_to_hle_function_map.find(PC);
|
||||
assert(iter != m_addr_to_hle_function_map.end());
|
||||
|
||||
auto return_to_caller = iter->second(*this);
|
||||
if (return_to_caller)
|
||||
{
|
||||
SetBranch(GPR[0]._u32[3] & 0x3fffc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -248,6 +248,24 @@ public:
|
||||
{
|
||||
_u32[1+slice] |= exceptions;
|
||||
}
|
||||
|
||||
// Write the FPSCR
|
||||
void Write(u128 & r)
|
||||
{
|
||||
_u32[3] = r._u32[3] & 0x00000F07;
|
||||
_u32[2] = r._u32[2] & 0x00003F07;
|
||||
_u32[1] = r._u32[1] & 0x00003F07;
|
||||
_u32[0] = r._u32[0] & 0x00000F07;
|
||||
}
|
||||
|
||||
// Read the FPSCR
|
||||
void Read(u128 & r)
|
||||
{
|
||||
r._u32[3] = _u32[3];
|
||||
r._u32[2] = _u32[2];
|
||||
r._u32[1] = _u32[1];
|
||||
r._u32[0] = _u32[0];
|
||||
}
|
||||
};
|
||||
|
||||
union SPU_SNRConfig_hdr
|
||||
@ -287,6 +305,8 @@ public:
|
||||
u32 m_event_mask;
|
||||
u32 m_events;
|
||||
|
||||
std::unordered_map<u32, std::function<bool(SPUThread& SPU)>> m_addr_to_hle_function_map;
|
||||
|
||||
struct IntrTag
|
||||
{
|
||||
u32 enabled; // 1 == true
|
||||
@ -506,8 +526,35 @@ public:
|
||||
void WriteLS64 (const u32 lsa, const u64& data) const { vm::write64 (lsa + m_offset, data); }
|
||||
void WriteLS128(const u32 lsa, const u128& data) const { vm::write128(lsa + m_offset, data); }
|
||||
|
||||
void RegisterHleFunction(u32 addr, std::function<bool(SPUThread & SPU)> function)
|
||||
{
|
||||
m_addr_to_hle_function_map[addr] = function;
|
||||
WriteLS32(addr, 0x00000003); // STOP 3
|
||||
}
|
||||
|
||||
void UnregisterHleFunction(u32 addr)
|
||||
{
|
||||
WriteLS32(addr, 0x00200000); // NOP
|
||||
m_addr_to_hle_function_map.erase(addr);
|
||||
}
|
||||
|
||||
void UnregisterHleFunctions(u32 start_addr, u32 end_addr)
|
||||
{
|
||||
for (auto iter = m_addr_to_hle_function_map.begin(); iter != m_addr_to_hle_function_map.end();)
|
||||
{
|
||||
if (iter->first >= start_addr && iter->first <= end_addr)
|
||||
{
|
||||
WriteLS32(iter->first, 0x00200000); // NOP
|
||||
m_addr_to_hle_function_map.erase(iter++);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::function<void(SPUThread& SPU)> m_custom_task;
|
||||
std::function<u64(SPUThread& SPU)> m_code3_func;
|
||||
|
||||
public:
|
||||
SPUThread(CPUThreadType type = CPU_THREAD_SPU);
|
||||
@ -606,7 +653,7 @@ public:
|
||||
for (auto &arg : values)
|
||||
{
|
||||
u32 arg_size = align(u32(arg.size() + 1), stack_align);
|
||||
u32 arg_addr = Memory.MainMem.AllocAlign(arg_size, stack_align);
|
||||
u32 arg_addr = (u32)Memory.MainMem.AllocAlign(arg_size, stack_align);
|
||||
|
||||
std::strcpy(vm::get_ptr<char>(arg_addr), arg.c_str());
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -40,6 +40,7 @@ enum
|
||||
{
|
||||
CELL_SPURS_TASK_ERROR_AGAIN = 0x80410901,
|
||||
CELL_SPURS_TASK_ERROR_INVAL = 0x80410902,
|
||||
CELL_SPURS_TASK_ERROR_NOSYS = 0x80410903,
|
||||
CELL_SPURS_TASK_ERROR_NOMEM = 0x80410904,
|
||||
CELL_SPURS_TASK_ERROR_SRCH = 0x80410905,
|
||||
CELL_SPURS_TASK_ERROR_NOEXEC = 0x80410907,
|
||||
@ -91,6 +92,7 @@ enum SPURSKernelInterfaces
|
||||
CELL_SPURS_MAX_SPU = 8,
|
||||
CELL_SPURS_MAX_WORKLOAD = 16,
|
||||
CELL_SPURS_MAX_WORKLOAD2 = 32,
|
||||
CELL_SPURS_SYS_SERVICE_WORKLOAD_ID = 32,
|
||||
CELL_SPURS_MAX_PRIORITY = 16,
|
||||
CELL_SPURS_NAME_MAX_LENGTH = 15,
|
||||
CELL_SPURS_SIZE = 4096,
|
||||
@ -101,6 +103,12 @@ enum SPURSKernelInterfaces
|
||||
CELL_SPURS_INTERRUPT_VECTOR = 0x0,
|
||||
CELL_SPURS_LOCK_LINE = 0x80,
|
||||
CELL_SPURS_KERNEL_DMA_TAG_ID = 31,
|
||||
CELL_SPURS_KERNEL1_ENTRY_ADDR = 0x818,
|
||||
CELL_SPURS_KERNEL2_ENTRY_ADDR = 0x848,
|
||||
CELL_SPURS_KERNEL1_EXIT_ADDR = 0x808,
|
||||
CELL_SPURS_KERNEL2_EXIT_ADDR = 0x838,
|
||||
CELL_SPURS_KERNEL1_SELECT_WORKLOAD_ADDR = 0x290,
|
||||
CELL_SPURS_KERNEL2_SELECT_WORKLOAD_ADDR = 0x290,
|
||||
};
|
||||
|
||||
enum RangeofEventQueuePortNumbers
|
||||
@ -110,31 +118,6 @@ enum RangeofEventQueuePortNumbers
|
||||
CELL_SPURS_DYNAMIC_PORT_RANGE_BOTTOM = 63,
|
||||
};
|
||||
|
||||
enum SPURSTraceTypes
|
||||
{
|
||||
CELL_SPURS_TRACE_TAG_LOAD = 0x2a,
|
||||
CELL_SPURS_TRACE_TAG_MAP = 0x2b,
|
||||
CELL_SPURS_TRACE_TAG_START = 0x2c,
|
||||
CELL_SPURS_TRACE_TAG_STOP = 0x2d,
|
||||
CELL_SPURS_TRACE_TAG_USER = 0x2e,
|
||||
CELL_SPURS_TRACE_TAG_GUID = 0x2f,
|
||||
};
|
||||
|
||||
// SPURS task defines.
|
||||
enum TaskConstants
|
||||
{
|
||||
CELL_SPURS_MAX_TASK = 128,
|
||||
CELL_SPURS_TASK_TOP = 0x3000,
|
||||
CELL_SPURS_TASK_BOTTOM = 0x40000,
|
||||
CELL_SPURS_MAX_TASK_NAME_LENGTH = 32,
|
||||
};
|
||||
|
||||
class SPURSManager;
|
||||
class SPURSManagerEventFlag;
|
||||
class SPURSManagerTaskset;
|
||||
|
||||
struct CellSpurs;
|
||||
|
||||
enum SpursAttrFlags : u32
|
||||
{
|
||||
SAF_NONE = 0x0,
|
||||
@ -157,10 +140,128 @@ enum SpursFlags1 : u8
|
||||
{
|
||||
SF1_NONE = 0x0,
|
||||
|
||||
SF1_IS_SECOND = 0x40,
|
||||
SF1_32_WORKLOADS = 0x40,
|
||||
SF1_EXIT_IF_NO_WORK = 0x80,
|
||||
};
|
||||
|
||||
enum SpursWorkloadConstants : u64
|
||||
{
|
||||
// Workload states
|
||||
SPURS_WKL_STATE_NON_EXISTENT = 0,
|
||||
SPURS_WKL_STATE_PREPARING = 1,
|
||||
SPURS_WKL_STATE_RUNNABLE = 2,
|
||||
SPURS_WKL_STATE_SHUTTING_DOWN = 3,
|
||||
SPURS_WKL_STATE_REMOVABLE = 4,
|
||||
SPURS_WKL_STATE_INVALID = 5,
|
||||
|
||||
// GUID
|
||||
SPURS_GUID_SYS_WKL = 0x1BB841BF38F89D33ull,
|
||||
SPURS_GUID_TASKSET_PM = 0x836E915B2E654143ull,
|
||||
|
||||
// Image addresses
|
||||
SPURS_IMG_ADDR_SYS_SRV_WORKLOAD = 0x100,
|
||||
SPURS_IMG_ADDR_TASKSET_PM = 0x200,
|
||||
};
|
||||
|
||||
enum CellSpursModulePollStatus
|
||||
{
|
||||
CELL_SPURS_MODULE_POLL_STATUS_READYCOUNT = 1,
|
||||
CELL_SPURS_MODULE_POLL_STATUS_SIGNAL = 2,
|
||||
CELL_SPURS_MODULE_POLL_STATUS_FLAG = 4
|
||||
};
|
||||
|
||||
enum SpursTraceConstants
|
||||
{
|
||||
// Trace tag types
|
||||
CELL_SPURS_TRACE_TAG_KERNEL = 0x20,
|
||||
CELL_SPURS_TRACE_TAG_SERVICE = 0x21,
|
||||
CELL_SPURS_TRACE_TAG_TASK = 0x22,
|
||||
CELL_SPURS_TRACE_TAG_JOB = 0x23,
|
||||
CELL_SPURS_TRACE_TAG_OVIS = 0x24,
|
||||
CELL_SPURS_TRACE_TAG_LOAD = 0x2a,
|
||||
CELL_SPURS_TRACE_TAG_MAP = 0x2b,
|
||||
CELL_SPURS_TRACE_TAG_START = 0x2c,
|
||||
CELL_SPURS_TRACE_TAG_STOP = 0x2d,
|
||||
CELL_SPURS_TRACE_TAG_USER = 0x2e,
|
||||
CELL_SPURS_TRACE_TAG_GUID = 0x2f,
|
||||
|
||||
// Service incident
|
||||
CELL_SPURS_TRACE_SERVICE_INIT = 0x01,
|
||||
CELL_SPURS_TRACE_SERVICE_WAIT = 0x02,
|
||||
CELL_SPURS_TRACE_SERVICE_EXIT = 0x03,
|
||||
|
||||
// Task incident
|
||||
CELL_SPURS_TRACE_TASK_DISPATCH = 0x01,
|
||||
CELL_SPURS_TRACE_TASK_YIELD = 0x03,
|
||||
CELL_SPURS_TRACE_TASK_WAIT = 0x04,
|
||||
CELL_SPURS_TRACE_TASK_EXIT = 0x05,
|
||||
|
||||
// Trace mode flags
|
||||
CELL_SPURS_TRACE_MODE_FLAG_WRAP_BUFFER = 0x1,
|
||||
CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP = 0x2,
|
||||
CELL_SPURS_TRACE_MODE_FLAG_MASK = 0x3,
|
||||
};
|
||||
|
||||
// SPURS task constants
|
||||
enum SpursTaskConstants
|
||||
{
|
||||
CELL_SPURS_MAX_TASK = 128,
|
||||
CELL_SPURS_TASK_TOP = 0x3000,
|
||||
CELL_SPURS_TASK_BOTTOM = 0x40000,
|
||||
CELL_SPURS_MAX_TASK_NAME_LENGTH = 32,
|
||||
CELL_SPURS_TASK_ATTRIBUTE_REVISION = 1,
|
||||
CELL_SPURS_TASKSET_ATTRIBUTE_REVISION = 1,
|
||||
CELL_SPURS_TASK_EXECUTION_CONTEXT_SIZE = 1024,
|
||||
CELL_SPURS_TASKSET_PM_ENTRY_ADDR = 0xA00,
|
||||
CELL_SPURS_TASKSET_PM_SYSCALL_ADDR = 0xA70,
|
||||
|
||||
// Task syscall numbers
|
||||
CELL_SPURS_TASK_SYSCALL_EXIT = 0,
|
||||
CELL_SPURS_TASK_SYSCALL_YIELD = 1,
|
||||
CELL_SPURS_TASK_SYSCALL_WAIT_SIGNAL = 2,
|
||||
CELL_SPURS_TASK_SYSCALL_POLL = 3,
|
||||
CELL_SPURS_TASK_SYSCALL_RECV_WKL_FLAG = 4,
|
||||
|
||||
// Task poll status
|
||||
CELL_SPURS_TASK_POLL_FOUND_TASK = 1,
|
||||
CELL_SPURS_TASK_POLL_FOUND_WORKLOAD = 2,
|
||||
};
|
||||
|
||||
enum CellSpursEventFlagWaitMode
|
||||
{
|
||||
CELL_SPURS_EVENT_FLAG_OR = 0,
|
||||
CELL_SPURS_EVENT_FLAG_AND = 1,
|
||||
CELL_SPURS_EVENT_FLAG_WAIT_MODE_LAST = CELL_SPURS_EVENT_FLAG_AND,
|
||||
};
|
||||
|
||||
enum CellSpursEventFlagClearMode
|
||||
{
|
||||
CELL_SPURS_EVENT_FLAG_CLEAR_AUTO = 0,
|
||||
CELL_SPURS_EVENT_FLAG_CLEAR_MANUAL = 1,
|
||||
CELL_SPURS_EVENT_FLAG_CLEAR_LAST = CELL_SPURS_EVENT_FLAG_CLEAR_MANUAL,
|
||||
};
|
||||
|
||||
enum CellSpursEventFlagDirection
|
||||
{
|
||||
CELL_SPURS_EVENT_FLAG_SPU2SPU,
|
||||
CELL_SPURS_EVENT_FLAG_SPU2PPU,
|
||||
CELL_SPURS_EVENT_FLAG_PPU2SPU,
|
||||
CELL_SPURS_EVENT_FLAG_ANY2ANY,
|
||||
CELL_SPURS_EVENT_FLAG_LAST = CELL_SPURS_EVENT_FLAG_ANY2ANY,
|
||||
};
|
||||
|
||||
// Event flag constants
|
||||
enum SpursEventFlagConstants
|
||||
{
|
||||
CELL_SPURS_EVENT_FLAG_MAX_WAIT_SLOTS = 16,
|
||||
CELL_SPURS_EVENT_FLAG_INVALID_SPU_PORT = 0xFF,
|
||||
};
|
||||
|
||||
class SPURSManager;
|
||||
class SPURSManagerEventFlag;
|
||||
class SPURSManagerTaskset;
|
||||
struct CellSpurs;
|
||||
|
||||
struct CellSpursAttribute
|
||||
{
|
||||
static const uint align = 8;
|
||||
@ -208,6 +309,72 @@ struct CellSpursWorkloadFlag
|
||||
|
||||
typedef void(CellSpursShutdownCompletionEventHook)(vm::ptr<CellSpurs>, u32 wid, vm::ptr<void> arg);
|
||||
|
||||
struct CellSpursTraceInfo
|
||||
{
|
||||
static const u32 size = 0x80;
|
||||
static const u32 align = 16;
|
||||
|
||||
be_t<u32> spu_thread[8]; // 0x00
|
||||
be_t<u32> count[8]; // 0x20
|
||||
be_t<u32> spu_thread_grp; // 0x40
|
||||
be_t<u32> nspu; // 0x44
|
||||
//u8 padding[];
|
||||
};
|
||||
|
||||
struct CellSpursTracePacket
|
||||
{
|
||||
static const u32 size = 16;
|
||||
|
||||
struct
|
||||
{
|
||||
u8 tag;
|
||||
u8 length;
|
||||
u8 spu;
|
||||
u8 workload;
|
||||
be_t<u32> time;
|
||||
} header;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
be_t<u32> incident;
|
||||
be_t<u32> reserved;
|
||||
} service;
|
||||
|
||||
struct
|
||||
{
|
||||
be_t<u32> ea;
|
||||
be_t<u16> ls;
|
||||
be_t<u16> size;
|
||||
} load;
|
||||
|
||||
struct
|
||||
{
|
||||
be_t<u32> offset;
|
||||
be_t<u16> ls;
|
||||
be_t<u16> size;
|
||||
} map;
|
||||
|
||||
struct
|
||||
{
|
||||
s8 module[4];
|
||||
be_t<u16> level;
|
||||
be_t<u16> ls;
|
||||
} start;
|
||||
|
||||
struct
|
||||
{
|
||||
be_t<u32> incident;
|
||||
be_t<u32> taskId;
|
||||
} task;
|
||||
|
||||
be_t<u64> user;
|
||||
be_t<u64> guid;
|
||||
be_t<u64> stop;
|
||||
} data;
|
||||
};
|
||||
|
||||
// Core CellSpurs structures
|
||||
struct CellSpurs
|
||||
{
|
||||
@ -218,7 +385,7 @@ struct CellSpurs
|
||||
|
||||
struct _sub_str1
|
||||
{
|
||||
u8 unk0[0x20];
|
||||
u8 unk0[0x20]; // 0x00 - SPU exceptionh handler 0x08 - SPU exception handler args
|
||||
be_t<u64> sem; // 0x20
|
||||
u8 unk1[0x8];
|
||||
vm::bptr<CellSpursShutdownCompletionEventHook, 1, u64> hook; // 0x30
|
||||
@ -228,28 +395,29 @@ struct CellSpurs
|
||||
|
||||
static_assert(sizeof(_sub_str1) == 0x80, "Wrong _sub_str1 size");
|
||||
|
||||
struct _sub_str2
|
||||
struct _sub_str2 // Event port multiplexer
|
||||
{
|
||||
be_t<u32> unk0;
|
||||
be_t<u32> unk1;
|
||||
be_t<u32> unk2;
|
||||
be_t<u32> unk3;
|
||||
be_t<u32> unk0; // 0x00 Outstanding requests
|
||||
be_t<u32> unk1; // 0x04
|
||||
be_t<u32> unk2; // 0x08
|
||||
be_t<u32> unk3; // 0x0C
|
||||
be_t<u64> port; // 0x10
|
||||
u8 unk_[0x68];
|
||||
u8 unk_[0x68]; // 0x18 - The first u64 seems to be the start of a linked list. The linked list struct seems to be {u64 next; u64 data; u64 handler}
|
||||
};
|
||||
|
||||
static_assert(sizeof(_sub_str2) == 0x80, "Wrong _sub_str2 size");
|
||||
|
||||
struct _sub_str3
|
||||
struct WorkloadInfo
|
||||
{
|
||||
vm::bptr<const void, 1, u64> pm; // policy module
|
||||
be_t<u64> data; // spu argument
|
||||
vm::bptr<const void, 1, u64> addr; // Address of the executable
|
||||
be_t<u64> arg; // spu argument
|
||||
be_t<u32> size;
|
||||
atomic_t<u8> copy;
|
||||
be_t<u64> priority;
|
||||
atomic_t<u8> uniqueId; // The unique id is the same for all workloads with the same addr
|
||||
u8 pad[3];
|
||||
u8 priority[8];
|
||||
};
|
||||
|
||||
static_assert(sizeof(_sub_str3) == 0x20, "Wrong _sub_str3 size");
|
||||
static_assert(sizeof(WorkloadInfo) == 0x20, "Wrong WorkloadInfo size");
|
||||
|
||||
struct _sub_str4
|
||||
{
|
||||
@ -268,61 +436,68 @@ struct CellSpurs
|
||||
// real data
|
||||
struct
|
||||
{
|
||||
atomic_t<u8> wklReadyCount[0x20]; // 0x0 (index = wid)
|
||||
u8 wklA[0x10]; // 0x20 (packed 4-bit data, index = wid % 16, internal index = wid / 16)
|
||||
u8 wklB[0x10]; // 0x30 (packed 4-bit data, index = wid % 16, internal index = wid / 16)
|
||||
u8 wklMinCnt[0x10]; // 0x40 (seems only for first 0..15 wids)
|
||||
atomic_t<u8> wklMaxCnt[0x10]; // 0x50 (packed 4-bit data, index = wid % 16, internal index = wid / 16)
|
||||
atomic_t<u8> wklReadyCount1[0x10]; // 0x00 Number of SPUs requested by each workload (0..15 wids).
|
||||
atomic_t<u8> wklIdleSpuCountOrReadyCount2[0x10]; // 0x10 SPURS1: Number of idle SPUs requested by each workload (0..15 wids). SPURS2: Number of SPUs requested by each workload (16..31 wids).
|
||||
u8 wklCurrentContention[0x10]; // 0x20 Number of SPUs used by each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16.
|
||||
u8 wklPendingContention[0x10]; // 0x30 Number of SPUs that are pending to context switch to the workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16.
|
||||
u8 wklMinContention[0x10]; // 0x40 Min SPUs required for each workload. SPURS1: index = wid. SPURS2: Unused.
|
||||
atomic_t<u8> wklMaxContention[0x10]; // 0x50 Max SPUs that may be allocated to each workload. SPURS1: index = wid. SPURS2: packed 4-bit data, index = wid % 16, internal index = wid / 16.
|
||||
CellSpursWorkloadFlag wklFlag; // 0x60
|
||||
atomic_t<u16> wklSet1; // 0x70 (bitset for 0..15 wids)
|
||||
atomic_t<u8> x72; // 0x72
|
||||
u8 x73; // 0x73
|
||||
u8 flags1; // 0x74
|
||||
u8 x75; // 0x75
|
||||
atomic_t<u16> wklSignal1; // 0x70 (bitset for 0..15 wids)
|
||||
atomic_t<u8> sysSrvMessage; // 0x72
|
||||
u8 spuIdling; // 0x73
|
||||
u8 flags1; // 0x74 Type is SpursFlags1
|
||||
u8 sysSrvTraceControl; // 0x75
|
||||
u8 nSpus; // 0x76
|
||||
atomic_t<u8> flagRecv; // 0x77
|
||||
atomic_t<u16> wklSet2; // 0x78 (bitset for 16..32 wids)
|
||||
atomic_t<u8> wklFlagReceiver; // 0x77
|
||||
atomic_t<u16> wklSignal2; // 0x78 (bitset for 16..32 wids)
|
||||
u8 x7A[6]; // 0x7A
|
||||
atomic_t<u8> wklStat1[0x10]; // 0x80
|
||||
u8 wklD1[0x10]; // 0x90
|
||||
u8 wklE1[0x10]; // 0xA0
|
||||
atomic_t<u32> wklMskA; // 0xB0
|
||||
atomic_t<u32> wklMskB; // 0xB4
|
||||
u8 xB8[5]; // 0xB8
|
||||
atomic_t<u8> xBD; // 0xBD
|
||||
u8 xBE[2]; // 0xBE
|
||||
u8 xC0[8]; // 0xC0
|
||||
u8 xC8; // 0xC8
|
||||
atomic_t<u8> wklState1[0x10]; // 0x80 SPURS_WKL_STATE_*
|
||||
u8 wklStatus1[0x10]; // 0x90
|
||||
u8 wklEvent1[0x10]; // 0xA0
|
||||
atomic_t<u32> wklMskA; // 0xB0 - System service - Available workloads (32*u1)
|
||||
atomic_t<u32> wklMskB; // 0xB4 - System service - Available module id
|
||||
u32 xB8; // 0xB8
|
||||
u8 sysSrvExitBarrier; // 0xBC
|
||||
atomic_t<u8> sysSrvMsgUpdateWorkload; // 0xBD
|
||||
u8 xBE; // 0xBE
|
||||
u8 sysSrvMsgTerminate; // 0xBF
|
||||
u8 sysSrvWorkload[8]; // 0xC0
|
||||
u8 sysSrvOnSpu; // 0xC8
|
||||
u8 spuPort; // 0xC9
|
||||
u8 xCA; // 0xCA
|
||||
u8 xCB; // 0xCB
|
||||
u8 xCC; // 0xCC
|
||||
u8 xCD; // 0xCD
|
||||
u8 xCE; // 0xCE
|
||||
u8 sysSrvMsgUpdateTrace; // 0xCE
|
||||
u8 xCF; // 0xCF
|
||||
atomic_t<u8> wklStat2[0x10]; // 0xD0
|
||||
u8 wklD2[0x10]; // 0xE0
|
||||
u8 wklE2[0x10]; // 0xF0
|
||||
atomic_t<u8> wklState2[0x10]; // 0xD0 SPURS_WKL_STATE_*
|
||||
u8 wklStatus2[0x10]; // 0xE0
|
||||
u8 wklEvent2[0x10]; // 0xF0
|
||||
_sub_str1 wklF1[0x10]; // 0x100
|
||||
be_t<u64> unk22; // 0x900
|
||||
u8 unknown7[0x980 - 0x908];
|
||||
vm::bptr<CellSpursTraceInfo, 1, u64> traceBuffer; // 0x900
|
||||
be_t<u32> traceStartIndex[6]; // 0x908
|
||||
u8 unknown7[0x948 - 0x920]; // 0x920
|
||||
be_t<u64> traceDataSize; // 0x948
|
||||
be_t<u32> traceMode; // 0x950
|
||||
u8 unknown8[0x980 - 0x954]; // 0x954
|
||||
be_t<u64> semPrv; // 0x980
|
||||
be_t<u32> unk11; // 0x988
|
||||
be_t<u32> unk12; // 0x98C
|
||||
be_t<u64> unk13; // 0x990
|
||||
u8 unknown4[0xB00 - 0x998];
|
||||
_sub_str3 wklG1[0x10]; // 0xB00
|
||||
_sub_str3 wklSysG; // 0xD00
|
||||
WorkloadInfo wklInfo1[0x10]; // 0xB00
|
||||
WorkloadInfo wklInfoSysSrv; // 0xD00
|
||||
be_t<u64> ppu0; // 0xD20
|
||||
be_t<u64> ppu1; // 0xD28
|
||||
be_t<u32> spuTG; // 0xD30
|
||||
be_t<u32> spuTG; // 0xD30 - SPU thread group
|
||||
be_t<u32> spus[8]; // 0xD34
|
||||
u8 unknown3[0xD5C - 0xD54];
|
||||
be_t<u32> queue; // 0xD5C
|
||||
be_t<u32> port; // 0xD60
|
||||
atomic_t<u8> xD64; // 0xD64
|
||||
atomic_t<u8> xD65; // 0xD65
|
||||
atomic_t<u8> xD66; // 0xD66
|
||||
be_t<u32> queue; // 0xD5C - Event queue
|
||||
be_t<u32> port; // 0xD60 - Event port
|
||||
atomic_t<u8> xD64; // 0xD64 - SPURS handler dirty
|
||||
atomic_t<u8> xD65; // 0xD65 - SPURS handler waiting
|
||||
atomic_t<u8> xD66; // 0xD66 - SPURS handler exiting
|
||||
atomic_t<u32> enableEH; // 0xD68
|
||||
be_t<u32> exception; // 0xD6C
|
||||
sys_spu_image spuImg; // 0xD70
|
||||
@ -334,14 +509,14 @@ struct CellSpurs
|
||||
be_t<u32> unk5; // 0xD9C
|
||||
be_t<u32> revision; // 0xDA0
|
||||
be_t<u32> sdkVersion; // 0xDA4
|
||||
atomic_t<u64> spups; // 0xDA8
|
||||
atomic_t<u64> spups; // 0xDA8 - SPU port bits
|
||||
sys_lwmutex_t mutex; // 0xDB0
|
||||
sys_lwcond_t cond; // 0xDC8
|
||||
u8 unknown9[0xE00 - 0xDD0];
|
||||
_sub_str4 wklH1[0x10]; // 0xE00
|
||||
_sub_str2 sub3; // 0xF00
|
||||
u8 unknown6[0x1000 - 0xF80];
|
||||
_sub_str3 wklG2[0x10]; // 0x1000
|
||||
u8 unknown6[0x1000 - 0xF80]; // 0xF80 - Gloabl SPU exception handler 0xF88 - Gloabl SPU exception handlers args
|
||||
WorkloadInfo wklInfo2[0x10]; // 0x1000
|
||||
_sub_str1 wklF2[0x10]; // 0x1200
|
||||
_sub_str4 wklH2[0x10]; // 0x1A00
|
||||
} m;
|
||||
@ -353,15 +528,15 @@ struct CellSpurs
|
||||
} c;
|
||||
};
|
||||
|
||||
__forceinline atomic_t<u8>& wklStat(const u32 wid)
|
||||
__forceinline atomic_t<u8>& wklState(const u32 wid)
|
||||
{
|
||||
if (wid & 0x10)
|
||||
{
|
||||
return m.wklStat2[wid & 0xf];
|
||||
return m.wklState2[wid & 0xf];
|
||||
}
|
||||
else
|
||||
{
|
||||
return m.wklStat1[wid & 0xf];
|
||||
return m.wklState1[wid & 0xf];
|
||||
}
|
||||
}
|
||||
|
||||
@ -409,12 +584,104 @@ struct CellSpursWorkloadAttribute
|
||||
|
||||
struct CellSpursEventFlag
|
||||
{
|
||||
static const u32 align = 128;
|
||||
static const u32 size = 128;
|
||||
|
||||
union
|
||||
{
|
||||
// Raw data
|
||||
u8 _u8[size];
|
||||
|
||||
// Real data
|
||||
struct _CellSpursEventFlag
|
||||
{
|
||||
be_t<u16> events; // 0x00 Event bits
|
||||
be_t<u16> spuTaskPendingRecv; // 0x02 A bit is set to 1 when the condition of the SPU task using the slot are met and back to 0 when the SPU task unblocks
|
||||
be_t<u16> ppuWaitMask; // 0x04 Wait mask for blocked PPU thread
|
||||
u8 ppuWaitSlotAndMode; // 0x06 Top 4 bits: Wait slot number of the blocked PPU threa, Bottom 4 bits: Wait mode of the blocked PPU thread
|
||||
u8 ppuPendingRecv; // 0x07 Set to 1 when the blocked PPU thread's conditions are met and back to 0 when the PPU thread is unblocked
|
||||
be_t<u16> spuTaskUsedWaitSlots; // 0x08 A bit is set to 1 if the wait slot corresponding to the bit is used by an SPU task and 0 otherwise
|
||||
be_t<u16> spuTaskWaitMode; // 0x0A A bit is set to 1 if the wait mode for the SPU task corresponding to the bit is AND and 0 otherwise
|
||||
u8 spuPort; // 0x0C
|
||||
u8 isIwl; // 0x0D
|
||||
u8 direction; // 0x0E
|
||||
u8 clearMode; // 0x0F
|
||||
be_t<u16> spuTaskWaitMask[16]; // 0x10 Wait mask for blocked SPU tasks
|
||||
be_t<u16> pendingRecvTaskEvents[16]; // 0x30 The value of event flag when the wait condition for the thread/task was met
|
||||
u8 waitingTaskId[16]; // 0x50 Task id of waiting SPU threads
|
||||
u8 waitingTaskWklId[16]; // 0x60 Workload id of waiting SPU threads
|
||||
be_t<u64> addr; // 0x70
|
||||
be_t<u32> eventPortId; // 0x78
|
||||
be_t<u32> eventQueueId; // 0x7C
|
||||
} m;
|
||||
|
||||
static_assert(sizeof(_CellSpursEventFlag) == size, "Wrong _CellSpursEventFlag size");
|
||||
|
||||
SPURSManagerEventFlag *eventFlag;
|
||||
};
|
||||
};
|
||||
|
||||
union CellSpursTaskArgument
|
||||
{
|
||||
be_t<u128> _u128;
|
||||
};
|
||||
|
||||
union CellSpursTaskLsPattern
|
||||
{
|
||||
be_t<u128> _u128;
|
||||
};
|
||||
|
||||
struct CellSpursTaskset
|
||||
{
|
||||
static const u32 align = 128;
|
||||
static const u32 size = 6400;
|
||||
|
||||
struct TaskInfo
|
||||
{
|
||||
CellSpursTaskArgument args; // 0x00
|
||||
vm::bptr<u64, 1, u64> elf_addr; // 0x10
|
||||
be_t<u64> context_save_storage_and_alloc_ls_blocks; // 0x18 This is (context_save_storage_addr | allocated_ls_blocks)
|
||||
CellSpursTaskLsPattern ls_pattern; // 0x20
|
||||
};
|
||||
|
||||
static_assert(sizeof(TaskInfo) == 0x30, "Wrong TaskInfo size");
|
||||
|
||||
union
|
||||
{
|
||||
// Raw data
|
||||
u8 _u8[size];
|
||||
|
||||
// Real data
|
||||
struct _CellSpursTaskset
|
||||
{
|
||||
be_t<u128> running; // 0x00
|
||||
be_t<u128> ready; // 0x10
|
||||
be_t<u128> pending_ready; // 0x20
|
||||
be_t<u128> enabled; // 0x30
|
||||
be_t<u128> signalled; // 0x40
|
||||
be_t<u128> waiting; // 0x50
|
||||
vm::bptr<CellSpurs, 1, u64> spurs; // 0x60
|
||||
be_t<u64> args; // 0x68
|
||||
u8 enable_clear_ls; // 0x70
|
||||
u8 x71; // 0x71
|
||||
u8 wkl_flag_wait_task; // 0x72
|
||||
u8 last_scheduled_task; // 0x73
|
||||
be_t<u32> wid; // 0x74
|
||||
be_t<u64> x78; // 0x78
|
||||
TaskInfo task_info[128]; // 0x80
|
||||
vm::bptr<u64, 1, u64> exception_handler; // 0x1880
|
||||
vm::bptr<u64, 1, u64> exception_handler_arg; // 0x1888
|
||||
be_t<u32> size; // 0x1890
|
||||
u32 unk2; // 0x1894
|
||||
u32 event_flag_id1; // 0x1898
|
||||
u32 event_flag_id2; // 0x189C
|
||||
u8 unk3[0x60]; // 0x18A0
|
||||
} m;
|
||||
|
||||
static_assert(sizeof(_CellSpursTaskset) == size, "Wrong _CellSpursTaskset size");
|
||||
|
||||
SPURSManagerTaskset *taskset;
|
||||
};
|
||||
};
|
||||
|
||||
struct CellSpursInfo
|
||||
@ -446,63 +713,6 @@ struct CellSpursExceptionInfo
|
||||
be_t<u64> option;
|
||||
};
|
||||
|
||||
struct CellSpursTraceInfo
|
||||
{
|
||||
be_t<u32> spu_thread[8];
|
||||
be_t<u32> count[8];
|
||||
be_t<u32> spu_thread_grp;
|
||||
be_t<u32> nspu;
|
||||
//u8 padding[];
|
||||
};
|
||||
|
||||
struct CellTraceHeader
|
||||
{
|
||||
u8 tag;
|
||||
u8 length;
|
||||
u8 cpu;
|
||||
u8 thread;
|
||||
be_t<u32> time;
|
||||
};
|
||||
|
||||
struct CellSpursTracePacket
|
||||
{
|
||||
struct header_struct
|
||||
{
|
||||
u8 tag;
|
||||
u8 length;
|
||||
u8 spu;
|
||||
u8 workload;
|
||||
be_t<u32> time;
|
||||
} header;
|
||||
|
||||
struct data_struct
|
||||
{
|
||||
struct load_struct
|
||||
{
|
||||
be_t<u32> ea;
|
||||
be_t<u16> ls;
|
||||
be_t<u16> size;
|
||||
} load;
|
||||
|
||||
struct map_struct
|
||||
{
|
||||
be_t<u32> offset;
|
||||
be_t<u16> ls;
|
||||
be_t<u16> size;
|
||||
} map;
|
||||
|
||||
struct start_struct
|
||||
{
|
||||
s8 module[4];
|
||||
be_t<u16> level;
|
||||
be_t<u16> ls;
|
||||
} start;
|
||||
|
||||
be_t<u64> user;
|
||||
be_t<u64> guid;
|
||||
} data;
|
||||
};
|
||||
|
||||
// Exception handlers.
|
||||
//typedef void (*CellSpursGlobalExceptionEventHandler)(vm::ptr<CellSpurs> spurs, vm::ptr<const CellSpursExceptionInfo> info,
|
||||
// u32 id, vm::ptr<void> arg);
|
||||
@ -510,6 +720,13 @@ struct CellSpursTracePacket
|
||||
//typedef void (*CellSpursTasksetExceptionEventHandler)(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTaskset> taskset,
|
||||
// u32 idTask, vm::ptr<const CellSpursExceptionInfo> info, vm::ptr<void> arg);
|
||||
|
||||
struct CellSpursTaskNameBuffer
|
||||
{
|
||||
static const u32 align = 16;
|
||||
|
||||
char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct CellSpursTasksetInfo
|
||||
{
|
||||
//CellSpursTaskInfo taskInfo[CELL_SPURS_MAX_TASK];
|
||||
@ -525,25 +742,104 @@ struct CellSpursTasksetInfo
|
||||
|
||||
struct CellSpursTaskset2
|
||||
{
|
||||
be_t<u8> skip[10496];
|
||||
static const u32 align = 128;
|
||||
static const u32 size = 10496;
|
||||
|
||||
struct TaskInfo
|
||||
{
|
||||
CellSpursTaskArgument args;
|
||||
vm::bptr<u64, 1, u64> elf_addr;
|
||||
vm::bptr<u64, 1, u64> context_save_storage; // This is (context_save_storage_addr | allocated_ls_blocks)
|
||||
CellSpursTaskLsPattern ls_pattern;
|
||||
};
|
||||
|
||||
static_assert(sizeof(TaskInfo) == 0x30, "Wrong TaskInfo size");
|
||||
|
||||
union
|
||||
{
|
||||
// Raw data
|
||||
u8 _u8[size];
|
||||
|
||||
// Real data
|
||||
struct _CellSpursTaskset2
|
||||
{
|
||||
be_t<u32> running_set[4]; // 0x00
|
||||
be_t<u32> ready_set[4]; // 0x10
|
||||
be_t<u32> ready2_set[4]; // 0x20 - TODO: Find out what this is
|
||||
be_t<u32> enabled_set[4]; // 0x30
|
||||
be_t<u32> signal_received_set[4]; // 0x40
|
||||
be_t<u32> waiting_set[4]; // 0x50
|
||||
vm::bptr<CellSpurs, 1, u64> spurs; // 0x60
|
||||
be_t<u64> args; // 0x68
|
||||
u8 enable_clear_ls; // 0x70
|
||||
u8 x71; // 0x71
|
||||
u8 x72; // 0x72
|
||||
u8 last_scheduled_task; // 0x73
|
||||
be_t<u32> wid; // 0x74
|
||||
be_t<u64> x78; // 0x78
|
||||
TaskInfo task_info[128]; // 0x80
|
||||
vm::bptr<u64, 1, u64> exception_handler; // 0x1880
|
||||
vm::bptr<u64, 1, u64> exception_handler_arg; // 0x1888
|
||||
be_t<u32> size; // 0x1890
|
||||
u32 unk2; // 0x1894
|
||||
u32 event_flag_id1; // 0x1898
|
||||
u32 event_flag_id2; // 0x189C
|
||||
u8 unk3[0x1980 - 0x18A0]; // 0x18A0
|
||||
be_t<u128> task_exit_code[128]; // 0x1980
|
||||
u8 unk4[0x2900 - 0x2180]; // 0x2180
|
||||
} m;
|
||||
|
||||
static_assert(sizeof(_CellSpursTaskset2) == size, "Wrong _CellSpursTaskset2 size");
|
||||
};
|
||||
};
|
||||
|
||||
struct CellSpursTasksetAttribute
|
||||
{
|
||||
static const u32 align = 8;
|
||||
static const u32 size = 512;
|
||||
|
||||
union
|
||||
{
|
||||
// Raw data
|
||||
u8 _u8[size];
|
||||
|
||||
// Real data
|
||||
struct
|
||||
{
|
||||
be_t<u32> revision; // 0x00
|
||||
be_t<u32> sdk_version; // 0x04
|
||||
be_t<u64> args; // 0x08
|
||||
u8 priority[8]; // 0x10
|
||||
be_t<u32> max_contention; // 0x18
|
||||
vm::bptr<const char> name; // 0x1C
|
||||
be_t<u32> taskset_size; // 0x20
|
||||
be_t<s32> enable_clear_ls; // 0x24
|
||||
} m;
|
||||
};
|
||||
};
|
||||
|
||||
struct CellSpursTasksetAttribute2
|
||||
{
|
||||
be_t<u32> revision;
|
||||
be_t<u32> name_addr;
|
||||
be_t<u64> argTaskset;
|
||||
u8 priority[8];
|
||||
be_t<u32> maxContention;
|
||||
be_t<s32> enableClearLs;
|
||||
be_t<s32> CellSpursTaskNameBuffer_addr; //??? *taskNameBuffer
|
||||
//be_t<u32> __reserved__[];
|
||||
};
|
||||
static const u32 align = 8;
|
||||
static const u32 size = 512;
|
||||
|
||||
// cellSpurs task structures.
|
||||
struct CellSpursTaskNameBuffer
|
||||
{
|
||||
char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH];
|
||||
union
|
||||
{
|
||||
// Raw data
|
||||
u8 _u8[size];
|
||||
|
||||
// Real data
|
||||
struct
|
||||
{
|
||||
be_t<u32> revision; // 0x00
|
||||
vm::bptr<const char> name; // 0x04
|
||||
be_t<u64> args; // 0x08
|
||||
u8 priority[8]; // 0x10
|
||||
be_t<u32> max_contention; // 0x18
|
||||
be_t<s32> enable_clear_ls; // 0x1C
|
||||
vm::bptr<CellSpursTaskNameBuffer> task_name_buffer; // 0x20
|
||||
} m;
|
||||
};
|
||||
};
|
||||
|
||||
struct CellSpursTraceTaskData
|
||||
@ -552,21 +848,6 @@ struct CellSpursTraceTaskData
|
||||
be_t<u32> task;
|
||||
};
|
||||
|
||||
typedef be_t<u32> be_u32;
|
||||
typedef be_t<u64> be_u64;
|
||||
|
||||
struct CellSpursTaskArgument
|
||||
{
|
||||
be_u32 u32[4];
|
||||
be_u64 u64[2];
|
||||
};
|
||||
|
||||
struct CellSpursTaskLsPattern
|
||||
{
|
||||
be_u32 u32[4];
|
||||
be_u64 u64[2];
|
||||
};
|
||||
|
||||
struct CellSpursTaskAttribute2
|
||||
{
|
||||
be_t<u32> revision;
|
||||
@ -604,7 +885,77 @@ struct CellSpursTaskBinInfo
|
||||
CellSpursTaskLsPattern lsPattern;
|
||||
};
|
||||
|
||||
class PPUThread;
|
||||
// The SPURS kernel context. This resides at 0x100 of the LS.
|
||||
struct SpursKernelContext
|
||||
{
|
||||
u8 tempArea[0x80]; // 0x100
|
||||
u8 wklLocContention[0x10]; // 0x180
|
||||
u8 wklLocPendingContention[0x10]; // 0x190
|
||||
u8 priority[0x10]; // 0x1A0
|
||||
u8 x1B0[0x10]; // 0x1B0
|
||||
vm::bptr<CellSpurs, 1, u64> spurs; // 0x1C0
|
||||
be_t<u32> spuNum; // 0x1C8
|
||||
be_t<u32> dmaTagId; // 0x1CC
|
||||
vm::bptr<const void, 1, u64> wklCurrentAddr; // 0x1D0
|
||||
be_t<u32> wklCurrentUniqueId; // 0x1D8
|
||||
be_t<u32> wklCurrentId; // 0x1DC
|
||||
be_t<u32> exitToKernelAddr; // 0x1E0
|
||||
be_t<u32> selectWorkloadAddr; // 0x1E4
|
||||
u8 moduleId[2]; // 0x1E8
|
||||
u8 sysSrvInitialised; // 0x1EA
|
||||
u8 spuIdling; // 0x1EB
|
||||
be_t<u16> wklRunnable1; // 0x1EC
|
||||
be_t<u16> wklRunnable2; // 0x1EE
|
||||
be_t<u32> x1F0; // 0x1F0
|
||||
be_t<u32> x1F4; // 0x1F4
|
||||
be_t<u32> x1F8; // 0x1F8
|
||||
be_t<u32> x1FC; // 0x1FC
|
||||
be_t<u32> x200; // 0x200
|
||||
be_t<u32> x204; // 0x204
|
||||
be_t<u32> x208; // 0x208
|
||||
be_t<u32> x20C; // 0x20C
|
||||
be_t<u64> traceBuffer; // 0x210
|
||||
be_t<u32> traceMsgCount; // 0x218
|
||||
be_t<u32> traceMaxCount; // 0x21C
|
||||
u8 wklUniqueId[0x10]; // 0x220
|
||||
u8 x230[0x280 - 0x230]; // 0x230
|
||||
be_t<u32> guid[4]; // 0x280
|
||||
};
|
||||
|
||||
static_assert(sizeof(SpursKernelContext) == 0x190, "Incorrect size for SpursKernelContext");
|
||||
|
||||
// The SPURS taskset policy module context. This resides at 0x2700 of the LS.
|
||||
struct SpursTasksetContext
|
||||
{
|
||||
u8 tempAreaTaskset[0x80]; // 0x2700
|
||||
u8 tempAreaTaskInfo[0x30]; // 0x2780
|
||||
be_t<u64> x27B0; // 0x27B0
|
||||
vm::bptr<CellSpursTaskset, 1, u64> taskset; // 0x27B8
|
||||
be_t<u32> kernelMgmtAddr; // 0x27C0
|
||||
be_t<u32> syscallAddr; // 0x27C4
|
||||
be_t<u32> x27C8; // 0x27C8
|
||||
be_t<u32> spuNum; // 0x27CC
|
||||
be_t<u32> dmaTagId; // 0x27D0
|
||||
be_t<u32> taskId; // 0x27D4
|
||||
u8 x27D8[0x2840 - 0x27D8]; // 0x27D8
|
||||
u8 moduleId[16]; // 0x2840
|
||||
u8 stackArea[0x2C80 - 0x2850]; // 0x2850
|
||||
be_t<u128> savedContextLr; // 0x2C80
|
||||
be_t<u128> savedContextSp; // 0x2C90
|
||||
be_t<u128> savedContextR80ToR127[48]; // 0x2CA0
|
||||
be_t<u128> savedContextFpscr; // 0x2FA0
|
||||
be_t<u32> savedWriteTagGroupQueryMask; // 0x2FB0
|
||||
be_t<u32> savedSpuWriteEventMask; // 0x2FB4
|
||||
be_t<u32> tasksetMgmtAddr; // 0x2FB8
|
||||
be_t<u32> guidAddr; // 0x2FBC
|
||||
be_t<u64> x2FC0; // 0x2FC0
|
||||
be_t<u64> x2FC8; // 0x2FC8
|
||||
be_t<u32> taskExitCode; // 0x2FD0
|
||||
be_t<u32> x2FD4; // 0x2FD4
|
||||
u8 x2FD8[0x3000 - 0x2FD8]; // 0x2FD8
|
||||
};
|
||||
|
||||
static_assert(sizeof(SpursTasksetContext) == 0x900, "Incorrect size for SpursTasksetContext");
|
||||
|
||||
s64 spursAttachLv2EventQueue(vm::ptr<CellSpurs> spurs, u32 queue, vm::ptr<u8> port, s32 isDynamic, bool wasCreated);
|
||||
s64 spursWakeUp(PPUThread& CPU, vm::ptr<CellSpurs> spurs);
|
||||
|
1677
rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp
Normal file
1677
rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1099,3 +1099,86 @@ s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr<u32> value)
|
||||
*value = (u32)t->cfg.value;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void sys_spu_thread_exit(SPUThread & spu, s32 status)
|
||||
{
|
||||
// Cancel any pending status update requests
|
||||
u128 r;
|
||||
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(0));
|
||||
while (spu.GetChannelCount(MFC_RdTagStat) != 1);
|
||||
spu.ReadChannel(r, MFC_RdTagStat);
|
||||
|
||||
// Wait for all pending DMA operations to complete
|
||||
spu.WriteChannel(MFC_WrTagMask, u128::from32r(0xFFFFFFFF));
|
||||
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(MFC_TAG_UPDATE_ALL));
|
||||
spu.ReadChannel(r, MFC_RdTagStat);
|
||||
|
||||
spu.WriteChannel(SPU_WrOutMbox, u128::from32r(status));
|
||||
spu.StopAndSignal(0x102);
|
||||
}
|
||||
|
||||
void sys_spu_thread_group_exit(SPUThread & spu, s32 status)
|
||||
{
|
||||
// Cancel any pending status update requests
|
||||
u128 r;
|
||||
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(0));
|
||||
while (spu.GetChannelCount(MFC_RdTagStat) != 1);
|
||||
spu.ReadChannel(r, MFC_RdTagStat);
|
||||
|
||||
// Wait for all pending DMA operations to complete
|
||||
spu.WriteChannel(MFC_WrTagMask, u128::from32r(0xFFFFFFFF));
|
||||
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(MFC_TAG_UPDATE_ALL));
|
||||
spu.ReadChannel(r, MFC_RdTagStat);
|
||||
|
||||
spu.WriteChannel(SPU_WrOutMbox, u128::from32r(status));
|
||||
spu.StopAndSignal(0x101);
|
||||
}
|
||||
|
||||
s32 sys_spu_thread_send_event(SPUThread & spu, u8 spup, u32 data0, u32 data1)
|
||||
{
|
||||
if (spup > 0x3F)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (spu.GetChannelCount(SPU_RdInMbox))
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
spu.WriteChannel(SPU_WrOutMbox, u128::from32r(data1));
|
||||
spu.WriteChannel(SPU_WrOutIntrMbox, u128::from32r((spup << 24) | (data0 & 0x00FFFFFF)));
|
||||
|
||||
u128 r;
|
||||
spu.ReadChannel(r, SPU_RdInMbox);
|
||||
return r._u32[3];
|
||||
}
|
||||
|
||||
s32 sys_spu_thread_switch_system_module(SPUThread & spu, u32 status)
|
||||
{
|
||||
if (spu.GetChannelCount(SPU_RdInMbox))
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
// Cancel any pending status update requests
|
||||
u128 r;
|
||||
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(0));
|
||||
while (spu.GetChannelCount(MFC_RdTagStat) != 1);
|
||||
spu.ReadChannel(r, MFC_RdTagStat);
|
||||
|
||||
// Wait for all pending DMA operations to complete
|
||||
spu.WriteChannel(MFC_WrTagMask, u128::from32r(0xFFFFFFFF));
|
||||
spu.WriteChannel(MFC_WrTagUpdate, u128::from32r(MFC_TAG_UPDATE_ALL));
|
||||
spu.ReadChannel(r, MFC_RdTagStat);
|
||||
|
||||
do
|
||||
{
|
||||
spu.WriteChannel(SPU_WrOutMbox, u128::from32r(status));
|
||||
spu.StopAndSignal(0x120);
|
||||
spu.ReadChannel(r, SPU_RdInMbox);
|
||||
}
|
||||
while (r._u32[3] == CELL_EBUSY);
|
||||
|
||||
return r._u32[3];
|
||||
}
|
||||
|
@ -204,3 +204,9 @@ s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, vm::ptr<u64> stat);
|
||||
s32 sys_raw_spu_read_puint_mb(u32 id, vm::ptr<u32> value);
|
||||
s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value);
|
||||
s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr<u32> value);
|
||||
|
||||
// SPU Calls
|
||||
void sys_spu_thread_exit(SPUThread & spu, s32 status);
|
||||
void sys_spu_thread_group_exit(SPUThread & spu, s32 status);
|
||||
s32 sys_spu_thread_send_event(SPUThread & spu, u8 spup, u32 data0, u32 data1);
|
||||
s32 sys_spu_thread_switch_system_module(SPUThread & spu, u32 status);
|
||||
|
@ -413,7 +413,7 @@ namespace loader
|
||||
return ok;
|
||||
}
|
||||
|
||||
handler::error_code elf32::load_data(u32 offset)
|
||||
handler::error_code elf32::load_data(u32 offset, bool skip_writeable)
|
||||
{
|
||||
Elf_Machine machine = (Elf_Machine)(u16)(m_ehdr.is_le() ? m_ehdr.data_le.e_machine : m_ehdr.data_be.e_machine);
|
||||
|
||||
@ -436,6 +436,11 @@ namespace loader
|
||||
return loading_error;
|
||||
}
|
||||
|
||||
if (skip_writeable == true && (phdr.data_be.p_flags & 2/*PF_W*/) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (filesz)
|
||||
{
|
||||
m_stream->Seek(handler::get_stream_offset() + offset);
|
||||
|
@ -132,7 +132,7 @@ namespace loader
|
||||
|
||||
error_code init(vfsStream& stream) override;
|
||||
error_code load() override;
|
||||
error_code load_data(u32 offset);
|
||||
error_code load_data(u32 offset, bool skip_writeable = false);
|
||||
|
||||
virtual ~elf32() = default;
|
||||
};
|
||||
|
@ -37,6 +37,7 @@
|
||||
<ClCompile Include="..\Utilities\SSemaphore.cpp" />
|
||||
<ClCompile Include="..\Utilities\StrFmt.cpp" />
|
||||
<ClCompile Include="..\Utilities\Thread.cpp" />
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSpursSpu.cpp" />
|
||||
<ClCompile Include="Crypto\aes.cpp" />
|
||||
<ClCompile Include="Crypto\ec.cpp" />
|
||||
<ClCompile Include="Crypto\key_vault.cpp" />
|
||||
@ -621,6 +622,7 @@
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>
|
||||
</AdditionalIncludeDirectories>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
@ -638,6 +640,7 @@
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;LLVM_AVAILABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>
|
||||
</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
@ -658,6 +661,7 @@
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;MSVC_CRT_MEMLEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>
|
||||
</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
@ -675,6 +679,7 @@
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>
|
||||
</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
@ -695,6 +700,7 @@
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<PreprocessorDefinitions>LLVM_AVAILABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>
|
||||
</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
|
@ -668,6 +668,9 @@
|
||||
<ClCompile Include="Emu\Audio\XAudio2\XAudio2Thread.cpp">
|
||||
<Filter>Emu\Audio\XAudio2</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\Modules\cellSpursSpu.cpp">
|
||||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\ARMv7\ARMv7Decoder.cpp">
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClCompile>
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include "Utilities/GNU.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user