diff --git a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp index 5b9d91b29c..8cd683990d 100644 --- a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp @@ -75,7 +75,7 @@ u32 gcmGetLocalMemorySize(u32 sdk_version) return 0x0E000000; // 224MB } -error_code gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict); +error_code gcmMapEaIoAddress(ppu_thread& ppu, u32 ea, u32 io, u32 size, bool is_strict); u32 gcmIoOffsetToAddress(u32 ioOffset) { @@ -369,7 +369,7 @@ error_code _cellGcmInitBody(ppu_thread& ppu, vm::pptr contex render->main_mem_size = 0x10000000; } - if (gcmMapEaIoAddress(ioAddress, 0, ioSize, false) != CELL_OK) + if (gcmMapEaIoAddress(ppu, ioAddress, 0, ioSize, false) != CELL_OK) { return CELL_GCM_ERROR_FAILURE; } @@ -950,14 +950,14 @@ error_code cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr address) return CELL_OK; } -error_code gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict) +error_code gcmMapEaIoAddress(ppu_thread& ppu, u32 ea, u32 io, u32 size, bool is_strict) { if (!size || (ea & 0xFFFFF) || (io & 0xFFFFF) || (size & 0xFFFFF)) { return CELL_GCM_ERROR_FAILURE; } - if (auto error = sys_rsx_context_iomap(0x55555555, io, ea, size, 0xe000000000000800ull | (u64{is_strict} << 60))) + if (auto error = sys_rsx_context_iomap(ppu, 0x55555555, io, ea, size, 0xe000000000000800ull | (u64{is_strict} << 60))) { return error; } @@ -977,17 +977,17 @@ error_code gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict) return CELL_OK; } -error_code cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size) +error_code cellGcmMapEaIoAddress(ppu_thread& ppu, u32 ea, u32 io, u32 size) { cellGcmSys.warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size); const auto cfg = g_fxo->get(); std::lock_guard lock(cfg->gcmio_mutex); - return gcmMapEaIoAddress(ea, io, size, false); + return gcmMapEaIoAddress(ppu, ea, io, size, false); } -error_code cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags) +error_code cellGcmMapEaIoAddressWithFlags(ppu_thread& ppu, u32 ea, u32 io, u32 size, u32 flags) { cellGcmSys.warning("cellGcmMapEaIoAddressWithFlags(ea=0x%x, io=0x%x, size=0x%x, flags=0x%x)", ea, io, size, flags); @@ -996,7 +996,7 @@ error_code cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags) const auto cfg = g_fxo->get(); std::lock_guard lock(cfg->gcmio_mutex); - return gcmMapEaIoAddress(ea, io, size, true); + return gcmMapEaIoAddress(ppu, ea, io, size, true); } error_code cellGcmMapLocalMemory(vm::ptr address, vm::ptr size) @@ -1016,7 +1016,7 @@ error_code cellGcmMapLocalMemory(vm::ptr address, vm::ptr size) return CELL_GCM_ERROR_FAILURE; } -error_code cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset) +error_code cellGcmMapMainMemory(ppu_thread& ppu, u32 ea, u32 size, vm::ptr offset) { cellGcmSys.warning("cellGcmMapMainMemory(ea=0x%x, size=0x%x, offset=*0x%x)", ea, size, offset); @@ -1034,7 +1034,7 @@ error_code cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset) { io <<= 20; - if (auto error = gcmMapEaIoAddress(ea, io, size, false)) + if (auto error = gcmMapEaIoAddress(ppu, ea, io, size, false)) { return error; } @@ -1074,11 +1074,11 @@ error_code cellGcmReserveIoMapSize(u32 size) return CELL_OK; } -error_code GcmUnmapIoAddress(gcm_config* cfg, u32 io) +error_code GcmUnmapIoAddress(ppu_thread& ppu, gcm_config* cfg, u32 io) { if (u32 ea = cfg->offsetTable.eaAddress[io >>= 20], size = cfg->IoMapTable[ea]; size) { - if (auto error = sys_rsx_context_iounmap(0x55555555, io, size << 20)) + if (auto error = sys_rsx_context_iounmap(ppu, 0x55555555, io, size << 20)) { return error; } @@ -1098,7 +1098,7 @@ error_code GcmUnmapIoAddress(gcm_config* cfg, u32 io) return CELL_GCM_ERROR_FAILURE; } -error_code cellGcmUnmapEaIoAddress(u32 ea) +error_code cellGcmUnmapEaIoAddress(ppu_thread& ppu, u32 ea) { cellGcmSys.warning("cellGcmUnmapEaIoAddress(ea=0x%x)", ea); @@ -1116,20 +1116,20 @@ error_code cellGcmUnmapEaIoAddress(u32 ea) if (const u32 io = cfg->offsetTable.ioAddress[ea] << 20; io < rsx::get_current_renderer()->main_mem_size) { - return GcmUnmapIoAddress(cfg, io); + return GcmUnmapIoAddress(ppu, cfg, io); } return CELL_GCM_ERROR_FAILURE; } -error_code cellGcmUnmapIoAddress(u32 io) +error_code cellGcmUnmapIoAddress(ppu_thread& ppu, u32 io) { cellGcmSys.warning("cellGcmUnmapIoAddress(io=0x%x)", io); const auto cfg = g_fxo->get(); std::lock_guard lock(cfg->gcmio_mutex); - return GcmUnmapIoAddress(cfg, io); + return GcmUnmapIoAddress(ppu, cfg, io); } error_code cellGcmUnreserveIoMapSize(u32 size) diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index d5c3a95449..73b13ffd1e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -87,15 +87,19 @@ void lv2_rsx_config::send_event(u64 data1, u64 event_flags, u64 data3) const } } -error_code sys_rsx_device_open() +error_code sys_rsx_device_open(cpu_thread& cpu) { + cpu.state += cpu_flag::wait; + sys_rsx.todo("sys_rsx_device_open()"); return CELL_OK; } -error_code sys_rsx_device_close() +error_code sys_rsx_device_close(cpu_thread& cpu) { + cpu.state += cpu_flag::wait; + sys_rsx.todo("sys_rsx_device_close()"); return CELL_OK; @@ -111,8 +115,10 @@ error_code sys_rsx_device_close() * @param a6 (IN): E.g. Immediate value passed in cellGcmSys is 16. * @param a7 (IN): E.g. Immediate value passed in cellGcmSys is 8. */ -error_code sys_rsx_memory_allocate(vm::ptr mem_handle, vm::ptr mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7) +error_code sys_rsx_memory_allocate(cpu_thread& cpu, vm::ptr mem_handle, vm::ptr mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7) { + cpu.state += cpu_flag::wait; + sys_rsx.warning("sys_rsx_memory_allocate(mem_handle=*0x%x, mem_addr=*0x%x, size=0x%x, flags=0x%llx, a5=0x%llx, a6=0x%llx, a7=0x%llx)", mem_handle, mem_addr, size, flags, a5, a6, a7); if (u32 addr = vm::falloc(rsx::constants::local_mem_base, size, vm::video)) @@ -130,8 +136,10 @@ error_code sys_rsx_memory_allocate(vm::ptr mem_handle, vm::ptr mem_add * lv2 SysCall 669 (0x29D): sys_rsx_memory_free * @param mem_handle (OUT): Context / ID, for allocated local memory generated by sys_rsx_memory_allocate */ -error_code sys_rsx_memory_free(u32 mem_handle) +error_code sys_rsx_memory_free(cpu_thread& cpu, u32 mem_handle) { + cpu.state += cpu_flag::wait; + sys_rsx.warning("sys_rsx_memory_free(mem_handle=0x%x)", mem_handle); if (!vm::check_addr(rsx::constants::local_mem_base)) @@ -275,8 +283,10 @@ error_code sys_rsx_context_allocate(cpu_thread& cpu, vm::ptr context_id, vm * lv2 SysCall 671 (0x29F): sys_rsx_context_free * @param context_id (IN): RSX context generated by sys_rsx_context_allocate to free the context. */ -error_code sys_rsx_context_free(u32 context_id) +error_code sys_rsx_context_free(cpu_thread& cpu, u32 context_id) { + cpu.state += cpu_flag::wait; + sys_rsx.todo("sys_rsx_context_free(context_id=0x%x)", context_id); auto rsx_cfg = g_fxo->get(); @@ -299,8 +309,10 @@ error_code sys_rsx_context_free(u32 context_id) * @param size (IN): Size of mapping area in bytes. E.g. 0x00200000 * @param flags (IN): */ -error_code sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags) +error_code sys_rsx_context_iomap(cpu_thread& cpu, u32 context_id, u32 io, u32 ea, u32 size, u64 flags) { + cpu.state += cpu_flag::wait; + sys_rsx.warning("sys_rsx_context_iomap(context_id=0x%x, io=0x%x, ea=0x%x, size=0x%x, flags=0x%llx)", context_id, io, ea, size, flags); const auto render = rsx::get_current_renderer(); @@ -317,7 +329,6 @@ error_code sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 f } // Wait until we have no active RSX locks and reserve iomap for use. Must do so before acquiring vm lock to avoid deadlocks - vm::temporary_unlock(*get_current_cpu_thread()); rsx::reservation_lock rsx_lock(ea, size); vm::reader_lock rlock; @@ -356,8 +367,10 @@ error_code sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 f * @param io (IN): IO address. E.g. 0x00600000 (Start page 6) * @param size (IN): Size to unmap in byte. E.g. 0x00200000 */ -error_code sys_rsx_context_iounmap(u32 context_id, u32 io, u32 size) +error_code sys_rsx_context_iounmap(cpu_thread& cpu, u32 context_id, u32 io, u32 size) { + cpu.state += cpu_flag::wait; + sys_rsx.warning("sys_rsx_context_iounmap(context_id=0x%x, io=0x%x, size=0x%x)", context_id, io, size); const auto render = rsx::get_current_renderer(); @@ -400,6 +413,11 @@ error_code sys_rsx_context_iounmap(u32 context_id, u32 io, u32 size) */ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6) { + if (auto cpu = get_current_cpu_thread()) + { + cpu->state += cpu_flag::wait; + } + // Flip/queue/reset flip/flip event/user command/vblank as trace to help with log spam if (package_id == 0x102 || package_id == 0x103 || package_id == 0x10a || package_id == 0xFEC || package_id == 0xFED || package_id == 0xFEF) sys_rsx.trace("sys_rsx_context_attribute(context_id=0x%x, package_id=0x%x, a3=0x%llx, a4=0x%llx, a5=0x%llx, a6=0x%llx)", context_id, package_id, a3, a4, a5, a6); @@ -779,8 +797,10 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64 * @param a2 (OUT): Unused * @param dev_id (IN): An immediate value and always 8. (cellGcmInitPerfMon uses 11, 10, 9, 7, 12 successively). */ -error_code sys_rsx_device_map(vm::ptr dev_addr, vm::ptr a2, u32 dev_id) +error_code sys_rsx_device_map(cpu_thread& cpu, vm::ptr dev_addr, vm::ptr a2, u32 dev_id) { + cpu.state += cpu_flag::wait; + sys_rsx.warning("sys_rsx_device_map(dev_addr=*0x%x, a2=*0x%x, dev_id=0x%x)", dev_addr, a2, dev_id); if (dev_id != 8) { @@ -816,8 +836,10 @@ error_code sys_rsx_device_map(vm::ptr dev_addr, vm::ptr a2, u32 dev_id * lv2 SysCall 676 (0x2A4): sys_rsx_device_unmap * @param dev_id (IN): An immediate value and always 8. */ -error_code sys_rsx_device_unmap(u32 dev_id) +error_code sys_rsx_device_unmap(cpu_thread& cpu, u32 dev_id) { + cpu.state += cpu_flag::wait; + sys_rsx.todo("sys_rsx_device_unmap(dev_id=0x%x)", dev_id); return CELL_OK; @@ -826,8 +848,10 @@ error_code sys_rsx_device_unmap(u32 dev_id) /* * lv2 SysCall 677 (0x2A5): sys_rsx_attribute */ -error_code sys_rsx_attribute(u32 packageId, u32 a2, u32 a3, u32 a4, u32 a5) +error_code sys_rsx_attribute(cpu_thread& cpu, u32 packageId, u32 a2, u32 a3, u32 a4, u32 a5) { + cpu.state += cpu_flag::wait; + sys_rsx.warning("sys_rsx_attribute(packageId=0x%x, a2=0x%x, a3=0x%x, a4=0x%x, a5=0x%x)", packageId, a2, a3, a4, a5); return CELL_OK; diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.h b/rpcs3/Emu/Cell/lv2/sys_rsx.h index 40b1a8a38e..702c451dbc 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.h +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.h @@ -139,15 +139,15 @@ struct lv2_rsx_config }; // SysCalls -error_code sys_rsx_device_open(); -error_code sys_rsx_device_close(); -error_code sys_rsx_memory_allocate(vm::ptr mem_handle, vm::ptr mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7); -error_code sys_rsx_memory_free(u32 mem_handle); +error_code sys_rsx_device_open(cpu_thread& cpu); +error_code sys_rsx_device_close(cpu_thread& cpu); +error_code sys_rsx_memory_allocate(cpu_thread& cpu, vm::ptr mem_handle, vm::ptr mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7); +error_code sys_rsx_memory_free(cpu_thread& cpu, u32 mem_handle); error_code sys_rsx_context_allocate(cpu_thread& cpu, vm::ptr context_id, vm::ptr lpar_dma_control, vm::ptr lpar_driver_info, vm::ptr lpar_reports, u64 mem_ctx, u64 system_mode); -error_code sys_rsx_context_free(u32 context_id); -error_code sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 flags); -error_code sys_rsx_context_iounmap(u32 context_id, u32 io, u32 size); +error_code sys_rsx_context_free(cpu_thread& cpu, u32 context_id); +error_code sys_rsx_context_iomap(cpu_thread& cpu, u32 context_id, u32 io, u32 ea, u32 size, u64 flags); +error_code sys_rsx_context_iounmap(cpu_thread& cpu, u32 context_id, u32 io, u32 size); error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6); -error_code sys_rsx_device_map(vm::ptr dev_addr, vm::ptr a2, u32 dev_id); -error_code sys_rsx_device_unmap(u32 dev_id); -error_code sys_rsx_attribute(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5); +error_code sys_rsx_device_map(cpu_thread& cpu, vm::ptr dev_addr, vm::ptr a2, u32 dev_id); +error_code sys_rsx_device_unmap(cpu_thread& cpu, u32 dev_id); +error_code sys_rsx_attribute(cpu_thread& cpu, u32 a1, u32 a2, u32 a3, u32 a4, u32 a5); diff --git a/rpcs3/Emu/RSX/Capture/rsx_replay.cpp b/rpcs3/Emu/RSX/Capture/rsx_replay.cpp index aeff739b15..91777f7fe7 100644 --- a/rpcs3/Emu/RSX/Capture/rsx_replay.cpp +++ b/rpcs3/Emu/RSX/Capture/rsx_replay.cpp @@ -36,10 +36,10 @@ namespace rsx sys_memory_allocate(buffer_size, SYS_MEMORY_PAGE_SIZE_1M, contextInfo.ptr(&rsx_context::user_addr)); verify(HERE), (user_mem_addr = contextInfo->user_addr) != 0; - if (sys_rsx_device_map(contextInfo.ptr(&rsx_context::dev_addr), vm::null, 0x8) != CELL_OK) + if (sys_rsx_device_map(*this, contextInfo.ptr(&rsx_context::dev_addr), vm::null, 0x8) != CELL_OK) fmt::throw_exception("Capture Replay: sys_rsx_device_map failed!"); - if (sys_rsx_memory_allocate(contextInfo.ptr(&rsx_context::mem_handle), contextInfo.ptr(&rsx_context::mem_addr), 0x0F900000, 0, 0, 0, 0) != CELL_OK) + if (sys_rsx_memory_allocate(*this, contextInfo.ptr(&rsx_context::mem_handle), contextInfo.ptr(&rsx_context::mem_addr), 0x0F900000, 0, 0, 0, 0) != CELL_OK) fmt::throw_exception("Capture Replay: sys_rsx_memory_allocate failed!"); if (sys_rsx_context_allocate(*this, contextInfo.ptr(&rsx_context::context_id), contextInfo.ptr(&rsx_context::dma_addr), contextInfo.ptr(&rsx_context::driver_info), contextInfo.ptr(&rsx_context::reports_addr), contextInfo->mem_handle, 0) != CELL_OK) @@ -47,7 +47,7 @@ namespace rsx get_current_renderer()->main_mem_size = buffer_size; - if (sys_rsx_context_iomap(contextInfo->context_id, 0, user_mem_addr, buffer_size, 0xf000000000000800ull) != CELL_OK) + if (sys_rsx_context_iomap(*this, contextInfo->context_id, 0, user_mem_addr, buffer_size, 0xf000000000000800ull) != CELL_OK) fmt::throw_exception("Capture Replay: rsx io mapping failed!"); return contextInfo->context_id;