From 3b06214f88d5b208f4fb4b4ada16c69c0857b67d Mon Sep 17 00:00:00 2001 From: Eladash Date: Sat, 21 Sep 2019 13:25:53 +0300 Subject: [PATCH] Decrease memory stats in cellGemInit if needed Also: * fix state reset of cellGem * Check max_connect == 0 in cellGemInit --- rpcs3/Emu/Cell/Modules/cellGem.cpp | 83 +++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index c8db5944f9..df77d5e3a7 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -106,6 +106,7 @@ struct gem_config u32 connected_controllers; bool update_started{}; u32 camera_frame{}; + u32 memory_ptr{}; shared_mutex mtx; @@ -191,7 +192,7 @@ static bool check_gem_num(const u32 gem_num) */ static bool map_to_ds3_input(const u32 port_no, be_t& digital_buttons, be_t& analog_t) { - std::lock_guard lock(pad::g_pad_mutex); + std::scoped_lock lock(pad::g_pad_mutex); const auto handler = pad::get_current_handler(); @@ -279,7 +280,7 @@ static bool map_to_ds3_input(const u32 port_no, be_t& digital_buttons, be_t */ static bool map_ext_to_ds3_input(const u32 port_no, CellGemExtPortData& ext) { - std::lock_guard lock(pad::g_pad_mutex); + std::scoped_lock lock(pad::g_pad_mutex); const auto handler = pad::get_current_handler(); @@ -313,6 +314,8 @@ error_code cellGemCalibrate(u32 gem_num) const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -338,6 +341,8 @@ error_code cellGemClearStatusFlags(u32 gem_num, u64 mask) const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -387,6 +392,8 @@ error_code cellGemEnableCameraPitchAngleCorrection(u32 enable_flag) const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -403,6 +410,8 @@ error_code cellGemEnableMagnetometer(u32 gem_num, u32 enable) const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -430,12 +439,19 @@ error_code cellGemEnd() const auto gem = g_fxo->get(); - if (!gem->state.compare_and_swap_test(1, 0)) + std::scoped_lock lock(gem->mtx); + + if (gem->state.compare_and_swap_test(1, 0)) { - return CELL_GEM_ERROR_UNINITIALIZED; + if (u32 addr = gem->memory_ptr) + { + sys_memory_free(addr); + } + + return CELL_OK; } - return CELL_OK; + return CELL_GEM_ERROR_UNINITIALIZED; } error_code cellGemFilterState(u32 gem_num, u32 enable) @@ -444,6 +460,8 @@ error_code cellGemFilterState(u32 gem_num, u32 enable) const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -465,6 +483,8 @@ error_code cellGemForceRGB(u32 gem_num, float r, float g, float b) const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -612,6 +632,8 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -643,6 +665,8 @@ error_code cellGemGetInfo(vm::ptr info) const auto gem = g_fxo->get(); + std::shared_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -666,6 +690,11 @@ error_code cellGemGetInfo(vm::ptr info) return CELL_OK; } +u32 GemGetMemorySize(s32 max_connect) +{ + return max_connect <= 2 ? 0x120000 : 0x140000; +} + error_code cellGemGetMemorySize(s32 max_connect) { cellGem.warning("cellGemGetMemorySize(max_connect=%d)", max_connect); @@ -675,7 +704,7 @@ error_code cellGemGetMemorySize(s32 max_connect) return CELL_GEM_ERROR_INVALID_PARAMETER; } - return not_an_error(max_connect <= 2 ? 0x120000 : 0x140000); + return not_an_error(GemGetMemorySize(max_connect)); } error_code cellGemGetRGB(u32 gem_num, vm::ptr r, vm::ptr g, vm::ptr b) @@ -684,6 +713,8 @@ error_code cellGemGetRGB(u32 gem_num, vm::ptr r, vm::ptr g, vm::pt const auto gem = g_fxo->get(); + std::shared_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -708,6 +739,8 @@ error_code cellGemGetRumble(u32 gem_num, vm::ptr rumble) const auto gem = g_fxo->get(); + std::shared_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -729,6 +762,8 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptrget(); + std::shared_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -760,6 +795,8 @@ error_code cellGemGetStatusFlags(u32 gem_num, vm::ptr flags) const auto gem = g_fxo->get(); + std::shared_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -781,6 +818,8 @@ error_code cellGemGetTrackerHue(u32 gem_num, vm::ptr hue) const auto gem = g_fxo->get(); + std::shared_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -823,19 +862,41 @@ error_code cellGemInit(vm::cptr attribute) const auto gem = g_fxo->get(); - if (!attribute || !attribute->spurs_addr || attribute->max_connect > CELL_GEM_MAX_NUM) + if (!attribute || !attribute->spurs_addr || !attribute->max_connect || attribute->max_connect > CELL_GEM_MAX_NUM) { return CELL_GEM_ERROR_INVALID_PARAMETER; } + std::scoped_lock lock(gem->mtx); + if (!gem->state.compare_and_swap_test(0, 1)) { return CELL_GEM_ERROR_ALREADY_INITIALIZED; } + if (!attribute->memory_ptr) + { + vm::var addr(0); + + // Decrease memory stats + if (sys_memory_allocate(GemGetMemorySize(attribute->max_connect), SYS_MEMORY_PAGE_SIZE_64K, +addr) != CELL_OK) + { + return CELL_GEM_ERROR_RESOURCE_ALLOCATION_FAILED; + } + + gem->memory_ptr = *addr; + } + else + { + gem->memory_ptr = 0; + } + + gem->update_started = false; + gem->camera_frame = 0; + gem->status_flags = 0; gem->attribute = *attribute; - for (auto gem_num = 0; gem_num < CELL_GEM_MAX_NUM; gem_num++) + for (int gem_num = 0; gem_num < CELL_GEM_MAX_NUM; gem_num++) { gem->reset_controller(gem_num); } @@ -852,6 +913,8 @@ error_code cellGemInvalidateCalibration(s32 gem_num) const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -997,6 +1060,8 @@ error_code cellGemSetRumble(u32 gem_num, u8 rumble) const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED; @@ -1024,6 +1089,8 @@ error_code cellGemTrackHues(vm::cptr req_hues, vm::ptr res_hues) const auto gem = g_fxo->get(); + std::scoped_lock lock(gem->mtx); + if (!gem->state) { return CELL_GEM_ERROR_UNINITIALIZED;