From 5966c1a85b302c43c4cb8dff07401c4b08b6c73a Mon Sep 17 00:00:00 2001 From: Jake Date: Tue, 20 Jun 2017 18:12:30 -0500 Subject: [PATCH] stuff --- rpcs3/Emu/Cell/lv2/sys_event.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_event.h | 2 +- rpcs3/Emu/Cell/lv2/sys_rsx.cpp | 123 ++++++++++++++++++++++--------- rpcs3/Emu/RSX/RSXThread.cpp | 3 +- rpcs3/Emu/RSX/rsx_methods.cpp | 32 +++----- 5 files changed, 101 insertions(+), 61 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index b7f4c1ff4b..a867f60db9 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -414,7 +414,7 @@ error_code sys_event_port_disconnect(u32 eport_id) return CELL_OK; } -error_code sys_event_port_send(ppu_thread& ppu, u32 eport_id, u64 data1, u64 data2, u64 data3) +error_code sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3) { sys_event.trace("sys_event_port_send(eport_id=0x%x, data1=0x%llx, data2=0x%llx, data3=0x%llx)", eport_id, data1, data2, data3); diff --git a/rpcs3/Emu/Cell/lv2/sys_event.h b/rpcs3/Emu/Cell/lv2/sys_event.h index ab1ea7ee50..9f9fff268e 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.h +++ b/rpcs3/Emu/Cell/lv2/sys_event.h @@ -137,4 +137,4 @@ error_code sys_event_port_create(vm::ps3::ptr eport_id, s32 port_type, u64 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_disconnect(u32 eport_id); -error_code sys_event_port_send(ppu_thread& ppu, u32 event_port_id, u64 data1, u64 data2, u64 data3); +error_code sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3); diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index 5ac5cbd060..1bc68c76d9 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -13,27 +13,46 @@ namespace vm { using namespace ps3; } logs::channel sys_rsx("sys_rsx"); struct RsxDriverInfo { - be_t version_driver; - be_t version_gpu; - be_t memory_size; - be_t hardware_channel; - be_t nvcore_frequency; - be_t memory_frequency; - u8 unk[0x10A8]; + be_t version_driver; // 0x0 + be_t version_gpu; // 0x4 + be_t memory_size; // 0x8 + be_t hardware_channel; // 0xC + be_t nvcore_frequency; // 0x10 + be_t memory_frequency; // 0x14 + be_t unk1[4]; // 0x18 - 0x24 + be_t unk2; // 0x28 -- pgraph stuff + be_t reportsNotifyOffset;// 0x2C offset to notify memory + be_t reportsOffset; // 0x30 offset to reports memory + be_t reportsReportOffset;// 0x34 offset to reports in reports memory + be_t unk3[6]; // 0x38-0x54 + be_t systemModeFlags; // 0x54 + u8 unk4[0x105C]; // 0x10B0 struct Head { - be_t flip; - be_t unk[4]; - be_t unk1; - be_t unk2[5]; - be_t unk3; - be_t unk4[4]; - } head[8]; - be_t handlers; - be_t unk1; - be_t unk2; - be_t unk3; - be_t handler_queue; + be_t unk; // 0x0 + be_t lastFlip; // 0x8 last flip time + be_t flipFlags; // 0x10 flags to handle flip/queue + be_t unk1; // 0x14 + be_t unk2[2]; // 0x18 - 0x20 + be_t lastSecondVTime; // 0x28 last time for second vhandler freq + be_t vBlankCount; // 0x30 + be_t unk3; + } head[8]; // size = 0x40 + be_t unk5; // 0x12B0 + be_t unk6; // 0x12B4 + be_t unk7; // 0x12B8 + be_t unk8; // 0x12BC + be_t handlers; // 0x12C0 -- flags showing which handlers are set + be_t unk9; // 0x12C4 + be_t unk10; // 0x12C8 + be_t userCmdParam; // 0x12CC + be_t handler_queue; // 0x12D0 + be_t unk11; // 0x12D4 + // todo: theres more to this }; +template class Sizer { }; +Sizer foo; +static_assert(sizeof(RsxDriverInfo) == 0x12D8, "rsxSizeTest"); +static_assert(sizeof(RsxDriverInfo::Head) == 0x40, "rsxHeadSizeTest"); struct RsxDmaControl { u8 resv[0x40]; @@ -45,8 +64,8 @@ struct RsxDmaControl { }; struct RsxSemaphore { - be_t val; - be_t pad; + be_t val; + be_t pad; be_t timestamp; }; @@ -67,8 +86,8 @@ struct RsxReports { RsxReport report[2048]; }; -be_t g_rsx_event_port; -u32 g_driverInfo; +be_t g_rsx_event_port{ 0 }; +u32 g_driverInfo{ 0 }; s32 sys_rsx_device_open() { @@ -138,11 +157,18 @@ s32 sys_rsx_context_allocate(vm::ptr context_id, vm::ptr lpar_dma_cont *lpar_reports = 0x40300000; auto &driverInfo = vm::_ref(*lpar_driver_info); + + std::memset(&driverInfo, 0, sizeof(RsxDriverInfo)); + driverInfo.version_driver = 0x211; driverInfo.version_gpu = 0x5c; driverInfo.memory_size = 0xFE00000; driverInfo.nvcore_frequency = 500000000; driverInfo.memory_frequency = 650000000; + driverInfo.reportsNotifyOffset = 0x1000; + driverInfo.reportsOffset = 0; + driverInfo.reportsReportOffset = 0x1400; + driverInfo.systemModeFlags = system_mode; g_driverInfo = *lpar_driver_info; @@ -240,6 +266,12 @@ s32 sys_rsx_context_iounmap(u32 context_id, u32 io_addr, u32 a3, u32 size) s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6) { sys_rsx.todo("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); + + // hle/lle protection + if (g_driverInfo == 0) + return CELL_OK; + // todo: these event ports probly 'shouldnt' be here as i think its supposed to be interrupts that are sent from rsx somewhere in lv1 + const auto render = fxm::get(); auto &driverInfo = vm::_ref(g_driverInfo); switch(package_id) @@ -250,11 +282,19 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6 break; case 0x100: // Display mode set + break; case 0x101: // Display sync + // todo: this is wrong and should be 'second' vblank handler and freq + // although gcmSys seems just hardcoded at 1, so w/e + driverInfo.head[1].vBlankCount++; + driverInfo.head[1].lastSecondVTime = get_system_time(); + sys_event_port_send(g_rsx_event_port, 0, (1 << 1), 0); + sys_event_port_send(g_rsx_event_port, 0, (1 << 11), 0); // second vhandler break; case 0x102: // Display flip - driverInfo.head[a3].flip |= 0x80000000; + driverInfo.head[a3].flipFlags |= 0x80000000; + driverInfo.head[a3].lastFlip = get_system_time(); // should rsxthread set this? if (a3 == 0) sys_event_port_send(g_rsx_event_port, 0, (1 << 3), 0); if (a3 == 1) @@ -262,13 +302,12 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6 break; case 0x103: // Display Queue - driverInfo.head[a3].flip |= 0x40000000 | (1 << a4); + driverInfo.head[a3].flipFlags |= 0x40000000 | (1 << a4); if (a3 == 0) sys_event_port_send(g_rsx_event_port, 0, (1 << 5), 0); if (a3 == 1) sys_event_port_send(g_rsx_event_port, 0, (1 << 6), 0); break; - case 0x104: // Display buffer { u8 id = a3 & 0xFF; @@ -284,18 +323,24 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6 render->gcm_buffers[id].offset = offset; } break; + case 0x105: // destroy buffer? + break; case 0x106: // ? (Used by cellGcmInitPerfMon) break; - - case 0x10a: // ? + case 0x108: // ? set interrupt freq? + break; + case 0x10a: // ? Involved in managing flip status through cellGcmResetFlipStatus + { if (a3 > 7) return -17; - driverInfo.head[a3].flip &= a4; - driverInfo.head[a3].flip |= a5; - break; + u32 flipStatus = driverInfo.head[a3].flipFlags; + flipStatus = (flipStatus & a4) | a5; + driverInfo.head[a3].flipFlags = flipStatus; + } + break; - case 0x10D: // ? + case 0x10D: // Called by cellGcmInitCursor break; case 0x300: // Tiles @@ -303,7 +348,8 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6 case 0x301: // Depth-buffer (Z-cull) break; - + case 0x302: // something with zcull + break; case 0x600: // Framebuffer setup break; @@ -316,6 +362,13 @@ s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u6 case 0x603: // Framebuffer close break; + case 0xFEF: // hack: user command + // 'custom' invalid package id for now + // as i think we need custom lv1 interrupts to handle this accurately + // this also should probly be set by rsxthread + driverInfo.userCmdParam = a4; + sys_event_port_send(g_rsx_event_port, 0, (1 << 7), 0); + break; default: return CELL_EINVAL; } @@ -357,9 +410,9 @@ s32 sys_rsx_device_unmap(u32 dev_id) return CELL_OK; } -s32 sys_rsx_attribute(u32 a1, u32 a2, u32 a3, u32 a4, u32 a5) +s32 sys_rsx_attribute(u32 packageId, u32 a2, u32 a3, u32 a4, u32 a5) { - sys_rsx.todo("sys_rsx_attribute(a1=0x%x, a2=0x%x, a3=0x%x, a4=0x%x, a5=0x%x)", a1, a2, a3, a4, a5); + sys_rsx.todo("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/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 07293c4247..4c94e330f5 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -5,6 +5,7 @@ #include "RSXThread.h" #include "Emu/Cell/PPUCallback.h" +#include "Emu/Cell/lv2/sys_rsx.h" #include "Common/BufferUtils.h" #include "rsx_methods.h" @@ -390,7 +391,7 @@ namespace rsx if (get_system_time() - start_time > vblank_count * 1000000 / 60) { vblank_count++; - + sys_rsx_context_attribute(0x55555555, 0x101, 0, 0, 0, 0); if (vblank_handler) { intr_thread->cmd_list diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index c8697cd9a7..17505b8338 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -13,8 +13,6 @@ #include -#include - template <> void fmt_class_string::format(std::string& out, u64 arg) { @@ -114,22 +112,6 @@ namespace rsx RsxReport report[2048]; }; - u64 ptimer_gettime() { - static struct PerformanceFreqHolder { - u64 value; - PerformanceFreqHolder() { - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - value = freq.QuadPart; - } - } freq; - - LARGE_INTEGER cycle; - QueryPerformanceCounter(&cycle); - const u64 sec = cycle.QuadPart / freq.value; - return sec * 1000000000 + (cycle.QuadPart % freq.value) * 1000000000 / freq.value; - } - namespace nv4097 { void clear(thread* rsx, u32 _reg, u32 arg) @@ -167,7 +149,7 @@ namespace rsx auto& sema = vm::ps3::_ref(rsx->label_addr); sema.semaphore[index].val = arg; sema.semaphore[index].pad = 0; - sema.semaphore[index].timestamp = ptimer_gettime(); + sema.semaphore[index].timestamp = get_system_time(); } void back_end_write_semaphore_release(thread* rsx, u32 _reg, u32 arg) @@ -188,7 +170,7 @@ namespace rsx auto& sema = vm::ps3::_ref(rsx->label_addr); sema.semaphore[index].val = val; sema.semaphore[index].pad = 0; - sema.semaphore[index].timestamp = ptimer_gettime(); + sema.semaphore[index].timestamp = get_system_time(); } @@ -964,6 +946,7 @@ namespace rsx void user_command(thread* rsx, u32, u32 arg) { + sys_rsx_context_attribute(0x55555555, 0xFEF, 0, arg, 0, 0); if (rsx->user_handler) { rsx->intr_thread->cmd_list @@ -979,6 +962,8 @@ namespace rsx namespace gcm { + // not entirely sure which one should actually do the flip, or if these should be handled seperately, + // so for now lets flip in queue and just let the driver deal with it template struct driver_flip { @@ -1566,13 +1551,14 @@ namespace rsx //NV0039 bind(); - // custom methods - bind(); + // lv1 hypervisor bind_array(); - bind_range(); bind_range(); + // custom + bind(); + return true; }(); }