diff --git a/rpcs3/Emu/Cell/lv2/sys_process.h b/rpcs3/Emu/Cell/lv2/sys_process.h index 906c82af71..ebd3ac0bcb 100644 --- a/rpcs3/Emu/Cell/lv2/sys_process.h +++ b/rpcs3/Emu/Cell/lv2/sys_process.h @@ -26,6 +26,7 @@ enum : u32 SYS_FS_FD_OBJECT = 0x73, SYS_LWCOND_OBJECT = 0x97, SYS_EVENT_FLAG_OBJECT = 0x98, + SYS_RSXAUDIO_OBJECT = 0x60, }; enum : u64 diff --git a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp index 0191ab5e23..e4c33239a1 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.cpp @@ -187,10 +187,6 @@ error_code sys_rsxaudio_finalize(u32 handle) rsxaudio_obj->init = false; vm::dealloc(rsxaudio_obj->shmem, vm::main); - for (const auto port : rsxaudio_obj->event_port) - { - idm::remove(port); - } idm::remove(handle); rsxaudio_thread.rsxaudio_ctx_allocated = false; @@ -284,32 +280,6 @@ error_code sys_rsxaudio_create_connection(u32 handle) { rsxaudio_obj->event_queue[2] = queue3; - if (auto port1 = idm::make(SYS_EVENT_PORT_LOCAL, 0)) - { - idm::remove(rsxaudio_obj->event_port[0]); - rsxaudio_obj->event_port[0] = port1; - - if (auto port2 = idm::make(SYS_EVENT_PORT_LOCAL, 0)) - { - idm::remove(rsxaudio_obj->event_port[1]); - rsxaudio_obj->event_port[1] = port2; - - if (auto port3 = idm::make(SYS_EVENT_PORT_LOCAL, 0)) - { - idm::remove(rsxaudio_obj->event_port[2]); - rsxaudio_obj->event_port[2] = port3; - - return CELL_OK; - } - - idm::remove(port2); - rsxaudio_obj->event_port[1] = 0; - } - - idm::remove(port1); - rsxaudio_obj->event_port[0] = 0; - } - return CELL_OK; } } @@ -365,8 +335,6 @@ error_code sys_rsxaudio_close_connection(u32 handle) for (u32 q_idx = 0; q_idx < SYS_RSXAUDIO_PORT_CNT; q_idx++) { - idm::remove(rsxaudio_obj->event_port[q_idx]); - rsxaudio_obj->event_port[q_idx] = 0; rsxaudio_obj->event_queue[q_idx].reset(); } @@ -445,9 +413,9 @@ error_code sys_rsxaudio_start_process(u32 handle) for (u32 q_idx = 0; q_idx < SYS_RSXAUDIO_PORT_CNT; q_idx++) { - if (auto queue = rsxaudio_obj->event_queue[q_idx].lock(); rsxaudio_obj->event_port[q_idx] && sh_page->ctrl.ringbuf[q_idx].active) + if (auto queue = rsxaudio_obj->event_queue[q_idx].lock(); queue && sh_page->ctrl.ringbuf[q_idx].active) { - queue->send(s64{process_getpid()} << 32 | u64{rsxaudio_obj->event_port[q_idx]}, q_idx, 0, 0); + queue->send(rsxaudio_obj->event_port_name[q_idx], q_idx, 0, 0); } } @@ -854,9 +822,9 @@ void rsxaudio_data_thread::extract_audio_data() // Too late to recover reset_periods = true; - if (auto queue = rsxaudio_obj->event_queue[dst_raw].lock(); rsxaudio_obj->event_port[dst_raw]) + if (auto queue = rsxaudio_obj->event_queue[dst_raw].lock()) { - queue->send(s64{process_getpid()} << 32 | u64{rsxaudio_obj->event_port[dst_raw]}, dst_raw, blk_idx, timestamp); + queue->send(rsxaudio_obj->event_port_name[dst_raw], dst_raw, blk_idx, timestamp); } } } @@ -2120,7 +2088,12 @@ rsxaudio_periodic_tmr::wait_result rsxaudio_periodic_tmr::wait(const std::functi } #elif defined(__linux__) epoll_event event[obj_wait_cnt]{}; - const auto wait_status = epoll_wait(epoll_fd, event, obj_wait_cnt, -1); + int wait_status = 0; + do + { + wait_status = epoll_wait(epoll_fd, event, obj_wait_cnt, -1); + } + while (wait_status == -EINTR); if (wait_status < 0 || wait_status > obj_wait_cnt) { @@ -2143,7 +2116,12 @@ rsxaudio_periodic_tmr::wait_result rsxaudio_periodic_tmr::wait(const std::functi } #elif defined(BSD) || defined(__APPLE__) struct kevent event[obj_wait_cnt]{}; - const auto wait_status = kevent(kq, nullptr, 0, event, obj_wait_cnt, nullptr); + int wait_status = 0; + do + { + wait_status = kevent(kq, nullptr, 0, event, obj_wait_cnt, nullptr); + } + while (wait_status == -EINTR); if (wait_status < 0 || wait_status > obj_wait_cnt) { diff --git a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.h b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.h index 9f3e48e2f0..33c6973f3b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsxaudio.h +++ b/rpcs3/Emu/Cell/lv2/sys_rsxaudio.h @@ -162,7 +162,9 @@ struct lv2_rsxaudio final : lv2_obj vm::addr_t shmem{}; std::array, SYS_RSXAUDIO_PORT_CNT> event_queue{}; - std::array event_port{}; + + // lv2 uses port memory addresses for their names + static constexpr std::array event_port_name{ 0x8000000000400100, 0x8000000000400200, 0x8000000000400300 }; lv2_rsxaudio() { @@ -316,14 +318,14 @@ struct rsxaudio_hw_param_t static constexpr u8 MAP_SILENT_CH = umax; - bool init = false; - hdmi_ch_cfg_t ch_cfg{}; - std::array info_frame{}; // TODO: check chstat and info_frame for info on audio layout, add default values - std::array chstat{}; + bool init = false; + hdmi_ch_cfg_t ch_cfg{}; + std::array info_frame{}; // TODO: check chstat and info_frame for info on audio layout, add default values + std::array chstat{}; - bool muted = true; - bool force_mute = true; - bool use_spdif_1 = false; // TODO: unused for now + bool muted = true; + bool force_mute = true; + bool use_spdif_1 = false; // TODO: unused for now }; u32 serial_freq_base = SYS_RSXAUDIO_FREQ_BASE_384K; diff --git a/rpcs3/Emu/Cell/lv2/sys_uart.cpp b/rpcs3/Emu/Cell/lv2/sys_uart.cpp index ed54e6b3e6..7284f8f981 100644 --- a/rpcs3/Emu/Cell/lv2/sys_uart.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_uart.cpp @@ -5,6 +5,7 @@ #include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/lv2/sys_sync.h" #include "Emu/Cell/lv2/sys_rsxaudio.h" +#include "Emu/Cell/lv2/sys_process.h" #include "sys_uart.h" @@ -1663,6 +1664,11 @@ error_code sys_uart_initialize(ppu_thread &ppu) sys_uart.trace("sys_uart_initialize()"); + if (!g_ps3_process_info.has_root_perm()) + { + return CELL_ENOSYS; + } + auto &vuart_thread = g_fxo->get(); if (vuart_thread.initialized.test_and_set()) @@ -1677,6 +1683,11 @@ error_code sys_uart_receive(ppu_thread &ppu, vm::ptr buffer, u64 size, u32 { sys_uart.trace("sys_uart_receive(buffer=*0x%x, size=0x%llx, mode=0x%x)", buffer, size, mode); + if (!g_ps3_process_info.has_root_perm()) + { + return CELL_ENOSYS; + } + if (!size) { return CELL_OK; @@ -1781,6 +1792,11 @@ error_code sys_uart_send(ppu_thread &ppu, vm::cptr buffer, u64 size, u32 m { sys_uart.trace("sys_uart_send(buffer=0x%x, size=0x%llx, mode=0x%x)", buffer, size, mode); + if (!g_ps3_process_info.has_root_perm()) + { + return CELL_ENOSYS; + } + if (!size) { return CELL_OK; @@ -1920,6 +1936,11 @@ error_code sys_uart_get_params(vm::ptr buffer) { sys_uart.trace("sys_uart_get_params(buffer=0x%x)", buffer); + if (!g_ps3_process_info.has_root_perm()) + { + return CELL_ENOSYS; + } + auto &vuart_thread = g_fxo->get(); if (!vuart_thread.initialized) diff --git a/rpcs3/rpcs3qt/kernel_explorer.cpp b/rpcs3/rpcs3qt/kernel_explorer.cpp index 98428aa5ed..e30f55cb78 100644 --- a/rpcs3/rpcs3qt/kernel_explorer.cpp +++ b/rpcs3/rpcs3qt/kernel_explorer.cpp @@ -29,6 +29,7 @@ #include "Emu/Cell/lv2/sys_net/lv2_socket.h" #include "Emu/Cell/lv2/sys_fs.h" #include "Emu/Cell/lv2/sys_interrupt.h" +#include "Emu/Cell/lv2/sys_rsxaudio.h" #include "Emu/Cell/Modules/cellSpurs.h" #include "Emu/RSX/RSXThread.h" @@ -242,6 +243,7 @@ void kernel_explorer::update() { SYS_FS_FD_OBJECT , tr("File Descriptors")}, { SYS_LWCOND_OBJECT , tr("Light Weight Condition Variables")}, { SYS_EVENT_FLAG_OBJECT , tr("Event Flags")}, + { SYS_RSXAUDIO_OBJECT , tr("RSXAudio Objects")}, { memory_containers , tr("Memory Containers")}, { ppu_threads , tr("PPU Threads")}, @@ -532,6 +534,25 @@ void kernel_explorer::update() ef.type, ef.key, ef.pattern.load(), +ef.waiters))); break; } + case SYS_RSXAUDIO_OBJECT: + { + auto& rao = static_cast(obj); + std::lock_guard lock(rao.mutex); + if (!rao.init) + { + break; + } + + QTreeWidgetItem* rao_obj = add_leaf(node, qstr(fmt::format(u8"RSXAudio 0x%08x: Shmem: 0x%08x", id, u32{rao.shmem}))); + for (u64 q_idx = 0; q_idx < rao.event_queue.size(); q_idx++) + { + if (const auto eq = rao.event_queue[q_idx].lock()) + { + add_leaf(rao_obj, qstr(fmt::format(u8"Event Queue %u: ID: 0x%08x", q_idx, eq->id))); + } + } + break; + } default: { add_leaf(node, qstr(fmt::format("Unknown object 0x%08x", id)));