diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 17c70482a8..623f2f94bc 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -187,7 +187,7 @@ const std::array s_ppu_syscall_table BIND_FUNC(sys_event_port_disconnect), //137 (0x089) BIND_FUNC(sys_event_port_send), //138 (0x08A) BIND_FUNC(sys_event_flag_get), //139 (0x08B) - null_func,//BIND_FUNC(sys_event_port_connect_ipc) //140 (0x08C) + BIND_FUNC(sys_event_port_connect_ipc), //140 (0x08C) BIND_FUNC(sys_timer_usleep), //141 (0x08D) BIND_FUNC(sys_timer_sleep), //142 (0x08E) null_func,//BIND_FUNC(sys_time_set_timezone) //143 (0x08F) ROOT diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index 3386105aab..775fe47921 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -323,7 +323,7 @@ error_code sys_event_port_create(vm::ptr eport_id, s32 port_type, u64 name) { sys_event.warning("sys_event_port_create(eport_id=*0x%x, port_type=%d, name=0x%llx)", eport_id, port_type, name); - if (port_type != SYS_EVENT_PORT_LOCAL) + if (port_type != SYS_EVENT_PORT_LOCAL && port_type != 3) { sys_event.error("sys_event_port_create(): unknown port type (%d)", port_type); return CELL_EINVAL; @@ -393,6 +393,36 @@ error_code sys_event_port_connect_local(u32 eport_id, u32 equeue_id) return CELL_OK; } +error_code sys_event_port_connect_ipc(u32 eport_id, u64 ipc_key) +{ + sys_event.warning("sys_event_port_connect_ipc(eport_id=0x%x, ipc_key=0x%x)", eport_id, ipc_key); + + auto queue = lv2_event_queue::find(ipc_key); + + writer_lock lock(id_manager::g_mutex); + + const auto port = idm::check_unlocked(eport_id); + + if (!port || !queue) + { + return CELL_ESRCH; + } + + if (port->type != 3) + { + return CELL_EINVAL; + } + + if (!port->queue.expired()) + { + return CELL_EISCONN; + } + + port->queue = std::move(queue); + + return CELL_ESRCH; +} + error_code sys_event_port_disconnect(u32 eport_id) { sys_event.warning("sys_event_port_disconnect(eport_id=0x%x)", eport_id); diff --git a/rpcs3/Emu/Cell/lv2/sys_event.h b/rpcs3/Emu/Cell/lv2/sys_event.h index 9f9fff268e..0323c0ef31 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.h +++ b/rpcs3/Emu/Cell/lv2/sys_event.h @@ -136,5 +136,6 @@ error_code sys_event_queue_drain(u32 event_queue_id); error_code sys_event_port_create(vm::ps3::ptr eport_id, s32 port_type, u64 name); error_code sys_event_port_destroy(u32 eport_id); error_code sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id); +error_code sys_event_port_connect_ipc(u32 eport_id, u64 ipc_key); error_code sys_event_port_disconnect(u32 eport_id); error_code sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);