rpcsx/rpcs3/Emu/Cell/lv2/sys_event.h

155 lines
3.6 KiB
C
Raw Normal View History

2020-12-05 13:08:24 +01:00
#pragma once
2016-04-14 00:23:53 +02:00
#include "sys_sync.h"
#include "Emu/Memory/vm_ptr.h"
2016-08-19 23:14:10 +02:00
class cpu_thread;
2015-03-04 05:42:04 +01:00
// Event Queue Type
enum : u32
2014-08-08 17:55:12 +02:00
{
SYS_PPU_QUEUE = 1,
SYS_SPU_QUEUE = 2,
};
2015-03-04 05:42:04 +01:00
// Event Queue Destroy Mode
enum : s32
{
2014-08-08 17:55:12 +02:00
SYS_EVENT_QUEUE_DESTROY_FORCE = 1,
};
// Event Queue Ipc Key
enum : u64
{
2015-07-19 23:29:40 +02:00
SYS_EVENT_QUEUE_LOCAL = 0,
};
2015-03-04 05:42:04 +01:00
// Event Port Type
enum : s32
{
2014-08-08 17:55:12 +02:00
SYS_EVENT_PORT_LOCAL = 1,
};
// Event Port Name
enum : u64
{
SYS_EVENT_PORT_NO_NAME = 0,
};
2015-03-04 05:42:04 +01:00
// Event Source Type
enum : u32
{
2014-08-08 17:55:12 +02:00
SYS_SPU_THREAD_EVENT_USER = 1,
2015-03-04 05:42:04 +01:00
SYS_SPU_THREAD_EVENT_DMA = 2, // not supported
};
2015-03-04 05:42:04 +01:00
// Event Source Key
enum : u64
{
SYS_SPU_THREAD_EVENT_USER_KEY = 0xFFFFFFFF53505501ull,
SYS_SPU_THREAD_EVENT_DMA_KEY = 0xFFFFFFFF53505502ull,
SYS_SPU_THREAD_EVENT_EXCEPTION_KEY = 0xFFFFFFFF53505503ull,
2014-08-08 17:55:12 +02:00
};
2015-07-09 17:30:37 +02:00
struct sys_event_queue_attribute_t
2014-08-08 17:55:12 +02:00
{
be_t<u32> protocol; // SYS_SYNC_PRIORITY or SYS_SYNC_FIFO
2014-09-19 02:19:22 +02:00
be_t<s32> type; // SYS_PPU_QUEUE or SYS_SPU_QUEUE
2017-02-03 22:36:04 +01:00
union
{
nse_t<u64, 1> name_u64;
char name[sizeof(u64)];
2017-02-03 22:36:04 +01:00
};
2014-08-08 17:55:12 +02:00
};
2015-03-04 05:42:04 +01:00
struct sys_event_t
2014-08-08 17:55:12 +02:00
{
be_t<u64> source;
be_t<u64> data1;
be_t<u64> data2;
be_t<u64> data3;
};
2017-02-03 22:36:04 +01:00
// Source, data1, data2, data3
using lv2_event = std::tuple<u64, u64, u64, u64>;
2016-04-14 00:23:53 +02:00
2017-02-03 22:36:04 +01:00
struct lv2_event_queue final : public lv2_obj
{
2017-01-25 18:50:30 +01:00
static const u32 id_base = 0x8d000000;
2020-06-09 17:35:14 +02:00
const lv2_protocol protocol;
2015-03-04 05:42:04 +01:00
const s32 type;
const u64 name;
2017-02-03 22:36:04 +01:00
const u64 key;
2015-03-04 05:42:04 +01:00
const s32 size;
2020-06-04 08:42:04 +02:00
atomic_t<u32> exists = 0; // Existence validation (workaround for shared-ptr ref-counting)
shared_mutex mutex;
2017-02-03 22:36:04 +01:00
std::deque<lv2_event> events;
std::deque<cpu_thread*> sq;
2016-04-14 00:23:53 +02:00
2017-02-03 22:36:04 +01:00
lv2_event_queue(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size)
2020-06-09 17:35:14 +02:00
: protocol{protocol}
2017-02-03 22:36:04 +01:00
, type(type)
, name(name)
, key(ipc_key)
, size(size)
2016-04-14 00:23:53 +02:00
{
}
2014-08-08 17:55:12 +02:00
CellError send(lv2_event);
2014-08-08 17:55:12 +02:00
CellError send(u64 source, u64 d1, u64 d2, u64 d3)
2017-02-03 22:36:04 +01:00
{
return send(std::make_tuple(source, d1, d2, d3));
}
2017-02-03 22:36:04 +01:00
// Get event queue by its global key
static std::shared_ptr<lv2_event_queue> find(u64 ipc_key);
// Check queue ptr validity (use 'exists' member)
static bool check(const std::weak_ptr<lv2_event_queue>&);
static bool check(const std::shared_ptr<lv2_event_queue>&);
2020-06-04 08:42:04 +02:00
CellError on_id_create()
{
exists++;
return {};
}
2014-08-08 17:55:12 +02:00
};
struct lv2_event_port final : lv2_obj
2014-08-08 17:55:12 +02:00
{
2017-01-25 18:50:30 +01:00
static const u32 id_base = 0x0e000000;
2017-02-03 22:36:04 +01:00
const s32 type; // Port type, must be SYS_EVENT_PORT_LOCAL
const u64 name; // Event source (generated from id and process id if not set)
2015-07-19 14:58:11 +02:00
2017-02-03 22:36:04 +01:00
std::weak_ptr<lv2_event_queue> queue; // Event queue this port is connected to
2014-08-08 17:55:12 +02:00
lv2_event_port(s32 type, u64 name)
2015-03-04 22:51:14 +01:00
: type(type)
, name(name)
2014-08-08 17:55:12 +02:00
{
}
};
class ppu_thread;
2014-09-19 02:19:22 +02:00
2017-02-03 22:36:04 +01:00
// Syscalls
error_code sys_event_queue_create(cpu_thread& cpu, vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attribute_t> attr, u64 event_queue_key, s32 size);
2017-02-06 19:36:46 +01:00
error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode);
2018-02-09 15:49:37 +01:00
error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> dummy_event, u64 timeout);
2019-07-14 17:06:02 +02:00
error_code sys_event_queue_tryreceive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> event_array, s32 size, vm::ptr<u32> number);
error_code sys_event_queue_drain(ppu_thread& ppu, u32 event_queue_id);
2017-02-03 22:36:04 +01:00
error_code sys_event_port_create(cpu_thread& cpu, vm::ptr<u32> eport_id, s32 port_type, u64 name);
2019-07-14 17:06:02 +02:00
error_code sys_event_port_destroy(ppu_thread& ppu, u32 eport_id);
error_code sys_event_port_connect_local(cpu_thread& cpu, u32 event_port_id, u32 event_queue_id);
2019-07-14 17:06:02 +02:00
error_code sys_event_port_connect_ipc(ppu_thread& ppu, u32 eport_id, u64 ipc_key);
error_code sys_event_port_disconnect(ppu_thread& ppu, u32 eport_id);
2017-07-26 04:57:43 +02:00
error_code sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);