From 5c24009eb5e95b5f7a90fc9d23ea2fc98d38615b Mon Sep 17 00:00:00 2001 From: brian218 Date: Sun, 16 Oct 2022 13:23:48 +0800 Subject: [PATCH] Implemented sys_game_watchdog syscalls --- rpcs3/Emu/Cell/PPUThread.cpp | 5 ++- rpcs3/Emu/Cell/lv2/lv2.cpp | 6 +-- rpcs3/Emu/Cell/lv2/sys_game.cpp | 75 ++++++++++++++++++++++++++++++--- rpcs3/Emu/Cell/lv2/sys_game.h | 5 ++- 4 files changed, 81 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 01c1c91a2e..a0dd39be94 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -3295,8 +3295,11 @@ bool ppu_initialize(const ppu_module& info, bool check_only) { std::unordered_map link_table { - { "sys_game_board_storage_read", reinterpret_cast(ppu_execute_syscall) }, + { "sys_game_watchdog_start", reinterpret_cast(ppu_execute_syscall) }, + { "sys_game_watchdog_stop", reinterpret_cast(ppu_execute_syscall) }, + { "sys_game_watchdog_clear", reinterpret_cast(ppu_execute_syscall) }, { "sys_game_get_system_sw_version", reinterpret_cast(ppu_execute_syscall) }, + { "sys_game_board_storage_read", reinterpret_cast(ppu_execute_syscall) }, { "__trap", reinterpret_cast(&ppu_trap) }, { "__error", reinterpret_cast(&ppu_error) }, { "__check", reinterpret_cast(&ppu_check) }, diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 248bc32955..ca776db0eb 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -420,9 +420,9 @@ const std::array, 1024> g_ppu_sysc BIND_SYSC(sys_uart_send), //369 (0x171) ROOT BIND_SYSC(sys_uart_get_params), //370 (0x172) ROOT uns_func, //371 (0x173) UNS - NULL_FUNC(sys_game_watchdog_start), //372 (0x174) - NULL_FUNC(sys_game_watchdog_stop), //373 (0x175) - NULL_FUNC(sys_game_watchdog_clear), //374 (0x176) + BIND_SYSC(_sys_game_watchdog_start), //372 (0x174) + BIND_SYSC(_sys_game_watchdog_stop), //373 (0x175) + BIND_SYSC(_sys_game_watchdog_clear), //374 (0x176) NULL_FUNC(sys_game_set_system_sw_version), //375 (0x177) ROOT BIND_SYSC(_sys_game_get_system_sw_version), //376 (0x178) ROOT NULL_FUNC(sys_sm_set_shop_mode), //377 (0x179) ROOT diff --git a/rpcs3/Emu/Cell/lv2/sys_game.cpp b/rpcs3/Emu/Cell/lv2/sys_game.cpp index 2b459b4cc1..40fc85febd 100644 --- a/rpcs3/Emu/Cell/lv2/sys_game.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_game.cpp @@ -2,12 +2,82 @@ #include "util/sysinfo.hpp" #include "Emu/Memory/vm_ptr.h" #include "Emu/Cell/ErrorCodes.h" +#include "Emu/System.h" #include "Emu/system_config.h" +#include + #include "sys_game.h" LOG_CHANNEL(sys_game); +atomic_t watchdog_stopped = true; +atomic_t watchdog_last_clear; +u64 get_timestamp() +{ + return (get_system_time() - Emu.GetPauseTime()); +} + +error_code _sys_game_watchdog_start(u32 timeout) +{ + sys_game.trace("sys_game_watchdog_start(timeout=%d)", timeout); + + if (!watchdog_stopped) + { + return CELL_EABORT; + } + + auto watchdog = [=]() + { + while (!watchdog_stopped) + { + if (Emu.IsStopped() || get_timestamp() - watchdog_last_clear > timeout * 1000000) + { + watchdog_stopped = true; + if (!Emu.IsStopped()) + { + sys_game.warning("Watchdog timeout! Restarting the game..."); + Emu.CallFromMainThread([]() + { + Emu.Restart(); + }); + } + break; + } + std::this_thread::sleep_for(1s); + } + }; + + watchdog_stopped = false; + watchdog_last_clear = get_timestamp(); + std::thread(watchdog).detach(); + + return CELL_OK; +} + +error_code _sys_game_watchdog_stop() +{ + sys_game.trace("sys_game_watchdog_stop()"); + + watchdog_stopped = true; + + return CELL_OK; +} + +error_code _sys_game_watchdog_clear() +{ + sys_game.trace("sys_game_watchdog_clear()"); + + watchdog_last_clear = get_timestamp(); + + return CELL_OK; +} + +u64 _sys_game_get_system_sw_version() +{ + return stof(utils::get_firmware_version()) * 10000; +} + error_code _sys_game_board_storage_read(vm::ptr buffer1, vm::ptr buffer2) { sys_game.trace("sys_game_board_storage_read(buffer1=*0x%x, buffer2=*0x%x)", buffer1, buffer2); @@ -35,8 +105,3 @@ error_code _sys_game_board_storage_read(vm::ptr buffer1, vm::ptr buffer2 return CELL_OK; } - -u64 _sys_game_get_system_sw_version() -{ - return stof(utils::get_firmware_version()) * 10000; -} diff --git a/rpcs3/Emu/Cell/lv2/sys_game.h b/rpcs3/Emu/Cell/lv2/sys_game.h index bebfb307f7..be2286dcde 100644 --- a/rpcs3/Emu/Cell/lv2/sys_game.h +++ b/rpcs3/Emu/Cell/lv2/sys_game.h @@ -1,4 +1,7 @@ #pragma once -error_code _sys_game_board_storage_read(vm::ptr buffer1, vm::ptr buffer2); +error_code _sys_game_watchdog_start(u32 timeout); +error_code _sys_game_watchdog_stop(); +error_code _sys_game_watchdog_clear(); u64 _sys_game_get_system_sw_version(); +error_code _sys_game_board_storage_read(vm::ptr buffer1, vm::ptr buffer2);