2014-06-25 00:38:34 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
2015-04-13 15:32:09 +02:00
|
|
|
#include "sys_event.h"
|
2015-03-05 14:18:06 +01:00
|
|
|
|
2014-09-19 02:19:22 +02:00
|
|
|
enum : s32
|
2014-08-13 19:55:35 +02:00
|
|
|
{
|
2015-09-10 15:09:31 +02:00
|
|
|
SYS_SPU_THREAD_GROUP_TYPE_NORMAL = 0x00,
|
|
|
|
|
SYS_SPU_THREAD_GROUP_TYPE_SEQUENTIAL = 0x01,
|
|
|
|
|
SYS_SPU_THREAD_GROUP_TYPE_SYSTEM = 0x02,
|
2014-08-13 19:55:35 +02:00
|
|
|
SYS_SPU_THREAD_GROUP_TYPE_MEMORY_FROM_CONTAINER = 0x04,
|
2015-09-10 15:09:31 +02:00
|
|
|
SYS_SPU_THREAD_GROUP_TYPE_NON_CONTEXT = 0x08,
|
2014-08-13 19:55:35 +02:00
|
|
|
SYS_SPU_THREAD_GROUP_TYPE_EXCLUSIVE_NON_CONTEXT = 0x18,
|
2014-09-19 02:19:22 +02:00
|
|
|
SYS_SPU_THREAD_GROUP_TYPE_COOPERATE_WITH_SYSTEM = 0x20,
|
2014-08-13 19:55:35 +02:00
|
|
|
};
|
|
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
enum
|
|
|
|
|
{
|
2015-09-10 15:09:31 +02:00
|
|
|
SYS_SPU_THREAD_GROUP_JOIN_GROUP_EXIT = 0x0001,
|
2014-06-25 00:38:34 +02:00
|
|
|
SYS_SPU_THREAD_GROUP_JOIN_ALL_THREADS_EXIT = 0x0002,
|
2015-09-10 15:09:31 +02:00
|
|
|
SYS_SPU_THREAD_GROUP_JOIN_TERMINATED = 0x0004
|
2014-06-25 00:38:34 +02:00
|
|
|
};
|
|
|
|
|
|
2014-09-19 21:11:43 +02:00
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
SYS_SPU_THREAD_GROUP_EVENT_RUN = 1,
|
|
|
|
|
SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION = 2,
|
|
|
|
|
SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE = 4,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum : u64
|
|
|
|
|
{
|
|
|
|
|
SYS_SPU_THREAD_GROUP_EVENT_RUN_KEY = 0xFFFFFFFF53505500ull,
|
|
|
|
|
SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION_KEY = 0xFFFFFFFF53505503ull,
|
|
|
|
|
SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE_KEY = 0xFFFFFFFF53505504ull,
|
|
|
|
|
};
|
|
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
enum : u32
|
2014-09-19 02:19:22 +02:00
|
|
|
{
|
2014-08-13 19:55:35 +02:00
|
|
|
SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED,
|
|
|
|
|
SPU_THREAD_GROUP_STATUS_INITIALIZED,
|
|
|
|
|
SPU_THREAD_GROUP_STATUS_READY,
|
|
|
|
|
SPU_THREAD_GROUP_STATUS_WAITING,
|
|
|
|
|
SPU_THREAD_GROUP_STATUS_SUSPENDED,
|
|
|
|
|
SPU_THREAD_GROUP_STATUS_WAITING_AND_SUSPENDED,
|
|
|
|
|
SPU_THREAD_GROUP_STATUS_RUNNING,
|
|
|
|
|
SPU_THREAD_GROUP_STATUS_STOPPED,
|
2015-07-09 17:30:37 +02:00
|
|
|
SPU_THREAD_GROUP_STATUS_UNKNOWN,
|
2014-08-13 19:55:35 +02:00
|
|
|
};
|
|
|
|
|
|
2014-09-19 02:19:22 +02:00
|
|
|
enum : s32
|
2014-06-25 00:38:34 +02:00
|
|
|
{
|
2014-09-19 02:19:22 +02:00
|
|
|
SYS_SPU_SEGMENT_TYPE_COPY = 1,
|
|
|
|
|
SYS_SPU_SEGMENT_TYPE_FILL = 2,
|
|
|
|
|
SYS_SPU_SEGMENT_TYPE_INFO = 4,
|
2014-06-25 00:38:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct sys_spu_thread_group_attribute
|
|
|
|
|
{
|
2015-03-04 22:51:14 +01:00
|
|
|
be_t<u32> nsize; // name length including NULL terminator
|
2016-08-19 23:14:10 +02:00
|
|
|
vm::ps3::bcptr<char> name;
|
2014-09-03 18:33:30 +02:00
|
|
|
be_t<s32> type;
|
2014-06-25 00:38:34 +02:00
|
|
|
be_t<u32> ct; // memory container id
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-19 02:19:22 +02:00
|
|
|
enum : u32
|
|
|
|
|
{
|
|
|
|
|
SYS_SPU_THREAD_OPTION_NONE = 0,
|
|
|
|
|
SYS_SPU_THREAD_OPTION_ASYNC_INTR_ENABLE = 1,
|
|
|
|
|
SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE = 2,
|
|
|
|
|
};
|
|
|
|
|
|
2014-06-25 00:38:34 +02:00
|
|
|
struct sys_spu_thread_attribute
|
|
|
|
|
{
|
2016-08-19 23:14:10 +02:00
|
|
|
vm::ps3::bcptr<char> name;
|
2014-06-25 00:38:34 +02:00
|
|
|
be_t<u32> name_len;
|
|
|
|
|
be_t<u32> option;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct sys_spu_thread_argument
|
|
|
|
|
{
|
|
|
|
|
be_t<u64> arg1;
|
|
|
|
|
be_t<u64> arg2;
|
|
|
|
|
be_t<u64> arg3;
|
|
|
|
|
be_t<u64> arg4;
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-19 02:19:22 +02:00
|
|
|
struct sys_spu_segment
|
|
|
|
|
{
|
|
|
|
|
be_t<s32> type; // copy, fill, info
|
|
|
|
|
be_t<u32> ls; // local storage address
|
|
|
|
|
be_t<s32> size;
|
|
|
|
|
|
|
|
|
|
union
|
|
|
|
|
{
|
2014-11-20 20:41:04 +01:00
|
|
|
be_t<u32> addr; // address or fill value
|
2014-09-19 02:19:22 +02:00
|
|
|
u64 pad;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2015-06-21 16:48:21 +02:00
|
|
|
CHECK_SIZE(sys_spu_segment, 0x18);
|
2014-09-19 02:19:22 +02:00
|
|
|
|
|
|
|
|
enum : u32
|
|
|
|
|
{
|
|
|
|
|
SYS_SPU_IMAGE_TYPE_USER = 0,
|
|
|
|
|
SYS_SPU_IMAGE_TYPE_KERNEL = 1,
|
|
|
|
|
};
|
|
|
|
|
|
2016-04-14 00:23:53 +02:00
|
|
|
struct sys_spu_image_t
|
2014-06-25 00:38:34 +02:00
|
|
|
{
|
2014-09-19 02:19:22 +02:00
|
|
|
be_t<u32> type; // user, kernel
|
|
|
|
|
be_t<u32> entry_point;
|
2016-08-19 23:14:10 +02:00
|
|
|
vm::ps3::bptr<sys_spu_segment> segs;
|
2014-09-19 02:19:22 +02:00
|
|
|
be_t<s32> nsegs;
|
2014-06-25 00:38:34 +02:00
|
|
|
};
|
|
|
|
|
|
2014-09-19 02:19:22 +02:00
|
|
|
enum : u32
|
2014-06-25 00:38:34 +02:00
|
|
|
{
|
2014-09-19 02:19:22 +02:00
|
|
|
SYS_SPU_IMAGE_PROTECT = 0,
|
|
|
|
|
SYS_SPU_IMAGE_DIRECT = 1,
|
2014-06-25 00:38:34 +02:00
|
|
|
};
|
|
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
struct spu_arg_t
|
|
|
|
|
{
|
|
|
|
|
u64 arg1;
|
|
|
|
|
u64 arg2;
|
|
|
|
|
u64 arg3;
|
|
|
|
|
u64 arg4;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// SPU Thread Group Join State Flag
|
|
|
|
|
enum : u32
|
|
|
|
|
{
|
2015-03-05 14:18:06 +01:00
|
|
|
SPU_TGJSF_IS_JOINING = (1 << 0),
|
|
|
|
|
SPU_TGJSF_TERMINATED = (1 << 1), // set if SPU Thread Group is terminated by sys_spu_thread_group_terminate
|
|
|
|
|
SPU_TGJSF_GROUP_EXIT = (1 << 2), // set if SPU Thread Group is terminated by sys_spu_thread_group_exit
|
2015-03-04 22:51:14 +01:00
|
|
|
};
|
|
|
|
|
|
2015-07-03 18:07:36 +02:00
|
|
|
class SPUThread;
|
|
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
struct lv2_spu_group
|
2015-03-04 22:51:14 +01:00
|
|
|
{
|
2017-01-25 18:50:30 +01:00
|
|
|
static const u32 id_base = 1; // Wrong?
|
|
|
|
|
static const u32 id_step = 1;
|
2017-01-29 17:50:18 +01:00
|
|
|
static const u32 id_count = 255;
|
2017-01-25 18:50:30 +01:00
|
|
|
|
2015-03-04 22:51:14 +01:00
|
|
|
const std::string name;
|
|
|
|
|
const u32 num; // SPU Number
|
|
|
|
|
const s32 type; // SPU Thread Group Type
|
|
|
|
|
const u32 ct; // Memory Container Id
|
|
|
|
|
|
2017-02-05 00:26:57 +01:00
|
|
|
semaphore<> mutex;
|
|
|
|
|
atomic_t<u32> init; // Initialization Counter
|
|
|
|
|
atomic_t<s32> prio; // SPU Thread Group Priority
|
|
|
|
|
atomic_t<u32> run_state; // SPU Thread Group State
|
|
|
|
|
atomic_t<s32> exit_status; // SPU Thread Group Exit Status
|
|
|
|
|
atomic_t<u32> join_state; // flags used to detect exit cause
|
|
|
|
|
cond_variable cv; // used to signal waiting PPU thread
|
|
|
|
|
|
2015-07-03 18:07:36 +02:00
|
|
|
std::array<std::shared_ptr<SPUThread>, 256> threads; // SPU Threads
|
2016-08-19 23:14:10 +02:00
|
|
|
std::array<vm::ps3::ptr<sys_spu_image_t>, 256> images; // SPU Images
|
2015-03-04 22:51:14 +01:00
|
|
|
std::array<spu_arg_t, 256> args; // SPU Thread Arguments
|
|
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
std::weak_ptr<lv2_event_queue> ep_run; // port for SYS_SPU_THREAD_GROUP_EVENT_RUN events
|
|
|
|
|
std::weak_ptr<lv2_event_queue> ep_exception; // TODO: SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION
|
|
|
|
|
std::weak_ptr<lv2_event_queue> ep_sysmodule; // TODO: SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE
|
2015-03-05 14:18:06 +01:00
|
|
|
|
2017-01-29 17:50:18 +01:00
|
|
|
lv2_spu_group(std::string name, u32 num, s32 prio, s32 type, u32 ct)
|
2015-03-04 22:51:14 +01:00
|
|
|
: name(name)
|
|
|
|
|
, num(num)
|
2017-02-05 00:26:57 +01:00
|
|
|
, init(0)
|
2015-03-04 22:51:14 +01:00
|
|
|
, prio(prio)
|
|
|
|
|
, type(type)
|
|
|
|
|
, ct(ct)
|
2017-02-05 00:26:57 +01:00
|
|
|
, run_state(SPU_THREAD_GROUP_STATUS_NOT_INITIALIZED)
|
2015-03-04 22:51:14 +01:00
|
|
|
, exit_status(0)
|
|
|
|
|
, join_state(0)
|
2014-06-25 00:38:34 +02:00
|
|
|
{
|
|
|
|
|
}
|
2015-04-13 15:32:09 +02:00
|
|
|
|
2017-02-03 22:36:04 +01:00
|
|
|
void send_run_event(u64 data1, u64 data2, u64 data3)
|
2015-04-13 15:32:09 +02:00
|
|
|
{
|
|
|
|
|
if (const auto queue = ep_run.lock())
|
|
|
|
|
{
|
2017-02-03 22:36:04 +01:00
|
|
|
queue->send(SYS_SPU_THREAD_GROUP_EVENT_RUN_KEY, data1, data2, data3);
|
2015-04-13 15:32:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-03 22:36:04 +01:00
|
|
|
void send_exception_event(u64 data1, u64 data2, u64 data3)
|
2015-04-13 15:32:09 +02:00
|
|
|
{
|
|
|
|
|
if (const auto queue = ep_exception.lock())
|
|
|
|
|
{
|
2017-02-03 22:36:04 +01:00
|
|
|
queue->send(SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION_KEY, data1, data2, data3);
|
2015-04-13 15:32:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-03 22:36:04 +01:00
|
|
|
void send_sysmodule_event(u64 data1, u64 data2, u64 data3)
|
2015-04-13 15:32:09 +02:00
|
|
|
{
|
|
|
|
|
if (const auto queue = ep_sysmodule.lock())
|
|
|
|
|
{
|
2017-02-03 22:36:04 +01:00
|
|
|
queue->send(SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE_KEY, data1, data2, data3);
|
2015-04-13 15:32:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
2014-06-25 00:38:34 +02:00
|
|
|
};
|
|
|
|
|
|
2016-07-27 23:43:22 +02:00
|
|
|
class ppu_thread;
|
2014-11-19 15:16:30 +01:00
|
|
|
|
2014-09-19 02:19:22 +02:00
|
|
|
// Aux
|
2016-04-14 00:23:53 +02:00
|
|
|
void LoadSpuImage(const fs::file& stream, u32& spu_ep, u32 addr);
|
|
|
|
|
u32 LoadSpuImage(const fs::file& stream, u32& spu_ep);
|
2014-09-19 02:19:22 +02:00
|
|
|
|
2017-02-05 13:48:11 +01:00
|
|
|
// Syscalls
|
|
|
|
|
|
|
|
|
|
error_code sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu);
|
|
|
|
|
error_code sys_spu_image_open(vm::ps3::ptr<sys_spu_image_t> img, vm::ps3::cptr<char> path);
|
|
|
|
|
error_code sys_spu_thread_initialize(vm::ps3::ptr<u32> thread, u32 group, u32 spu_num, vm::ps3::ptr<sys_spu_image_t>, vm::ps3::ptr<sys_spu_thread_attribute>, vm::ps3::ptr<sys_spu_thread_argument>);
|
|
|
|
|
error_code sys_spu_thread_set_argument(u32 id, vm::ps3::ptr<sys_spu_thread_argument> arg);
|
|
|
|
|
error_code sys_spu_thread_group_create(vm::ps3::ptr<u32> id, u32 num, s32 prio, vm::ps3::ptr<sys_spu_thread_group_attribute> attr);
|
|
|
|
|
error_code sys_spu_thread_group_destroy(u32 id);
|
2017-02-22 11:10:55 +01:00
|
|
|
error_code sys_spu_thread_group_start(ppu_thread&, u32 id);
|
2017-02-05 13:48:11 +01:00
|
|
|
error_code sys_spu_thread_group_suspend(u32 id);
|
|
|
|
|
error_code sys_spu_thread_group_resume(u32 id);
|
|
|
|
|
error_code sys_spu_thread_group_yield(u32 id);
|
|
|
|
|
error_code sys_spu_thread_group_terminate(u32 id, s32 value);
|
2017-02-06 19:36:46 +01:00
|
|
|
error_code sys_spu_thread_group_join(ppu_thread&, u32 id, vm::ps3::ptr<u32> cause, vm::ps3::ptr<u32> status);
|
2017-04-08 17:42:28 +02:00
|
|
|
error_code sys_spu_thread_group_set_priority(u32 id, s32 priority);
|
|
|
|
|
error_code sys_spu_thread_group_get_priority(u32 id, vm::ps3::ptr<s32> priority);
|
2017-02-05 13:48:11 +01:00
|
|
|
error_code sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et);
|
|
|
|
|
error_code sys_spu_thread_group_disconnect_event(u32 id, u32 et);
|
|
|
|
|
error_code sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq_id, u64 req, vm::ps3::ptr<u8> spup);
|
|
|
|
|
error_code sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup);
|
|
|
|
|
error_code sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type);
|
|
|
|
|
error_code sys_spu_thread_read_ls(u32 id, u32 address, vm::ps3::ptr<u64> value, u32 type);
|
|
|
|
|
error_code sys_spu_thread_write_spu_mb(u32 id, u32 value);
|
|
|
|
|
error_code sys_spu_thread_set_spu_cfg(u32 id, u64 value);
|
|
|
|
|
error_code sys_spu_thread_get_spu_cfg(u32 id, vm::ps3::ptr<u64> value);
|
|
|
|
|
error_code sys_spu_thread_write_snr(u32 id, u32 number, u32 value);
|
|
|
|
|
error_code sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup);
|
|
|
|
|
error_code sys_spu_thread_disconnect_event(u32 id, u32 event_type, u8 spup);
|
|
|
|
|
error_code sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num);
|
|
|
|
|
error_code sys_spu_thread_unbind_queue(u32 id, u32 spuq_num);
|
|
|
|
|
error_code sys_spu_thread_get_exit_status(u32 id, vm::ps3::ptr<u32> status);
|
|
|
|
|
|
|
|
|
|
error_code sys_raw_spu_create(vm::ps3::ptr<u32> id, vm::ps3::ptr<void> attr);
|
|
|
|
|
error_code sys_raw_spu_destroy(ppu_thread& ppu, u32 id);
|
|
|
|
|
error_code sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, vm::ps3::ptr<u32> intrtag);
|
|
|
|
|
error_code sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask);
|
|
|
|
|
error_code sys_raw_spu_get_int_mask(u32 id, u32 class_id, vm::ps3::ptr<u64> mask);
|
|
|
|
|
error_code sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat);
|
|
|
|
|
error_code sys_raw_spu_get_int_stat(u32 id, u32 class_id, vm::ps3::ptr<u64> stat);
|
|
|
|
|
error_code sys_raw_spu_read_puint_mb(u32 id, vm::ps3::ptr<u32> value);
|
|
|
|
|
error_code sys_raw_spu_set_spu_cfg(u32 id, u32 value);
|
|
|
|
|
error_code sys_raw_spu_get_spu_cfg(u32 id, vm::ps3::ptr<u32> value);
|