diff --git a/kernel/src/Plugins/FanController/FanController.cpp b/kernel/src/Plugins/FanController/FanController.cpp new file mode 100644 index 00000000..92fb2ad4 --- /dev/null +++ b/kernel/src/Plugins/FanController/FanController.cpp @@ -0,0 +1,75 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check it. +// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com + +#include "FanController.hpp" +#include +#include +#include + +using namespace Mira::Plugins; + +FanController::FanController() +{ +} + +FanController::~FanController() +{ +} + +void FanController::SetFanThreshhold(int fanController_input) +{ + if (fanController_input < 59 || fanController_input > 79) + { + WriteLog(LL_Error, "Unsafe fan controller setting: %i°C", fanController_input); + return; + } + + auto s_Thread = curthread; + if (s_Thread == nullptr) + { + WriteLog(LL_Error, "could not get current thread."); + return; + } + + if (fanController_orig == fanController_input) + { + WriteLog(LL_Info, "Fan controller already set to %i°C", fanController_input); + return; + } + + fanController_desired = fanController_input; + + int fd = kopen_t("/dev/icc_fan", 0x0000, 0, s_Thread); // O_RDONLY + if (fd <= 0) { + WriteLog(LL_Info, "unable to open \"/dev/icc_fan\""); + return; + } + + char data[10] = {0x00, 0x00, 0x00, 0x00, 0x00, (char)fanController_input, 0x00, 0x00, 0x00, 0x00}; + kioctl_t(fd, 0xC01C8F07, data, s_Thread); + kclose_t(fd, s_Thread); + + WriteLog(LL_Info, "Successfully set fan controller to %i°C", fanController_input); +} + +bool FanController::OnLoad() +{ + SetFanThreshhold(fanController_desired); + return true; +} + +bool FanController::OnUnload() +{ + SetFanThreshhold(fanController_orig); + return true; +} + +bool FanController::OnSuspend() +{ + return true; +} + +bool FanController::OnResume() +{ + return true; +} diff --git a/kernel/src/Plugins/FanController/FanController.hpp b/kernel/src/Plugins/FanController/FanController.hpp new file mode 100644 index 00000000..472bbc01 --- /dev/null +++ b/kernel/src/Plugins/FanController/FanController.hpp @@ -0,0 +1,26 @@ +#pragma once +#include +#include + +namespace Mira +{ + namespace Plugins + { + class FanController : public Mira::Utils::IModule + { + private: + int fanController_orig = 79; + int fanController_desired = 79; + public: + FanController(); + virtual ~FanController(); + + virtual const char* GetName() override { return "FanController"; } + virtual bool OnLoad() override; + virtual bool OnUnload() override; + virtual bool OnSuspend() override; + virtual bool OnResume() override; + void SetFanThreshhold(int fanController_input); + }; + } +} diff --git a/kernel/src/Plugins/PluginManager.cpp b/kernel/src/Plugins/PluginManager.cpp index 86e50742..b9767d1d 100644 --- a/kernel/src/Plugins/PluginManager.cpp +++ b/kernel/src/Plugins/PluginManager.cpp @@ -15,6 +15,7 @@ #include #include #include +#include // Utility functions #include @@ -39,7 +40,8 @@ PluginManager::PluginManager() : m_MorpheusEnabler(nullptr), m_RemotePlayEnabler(nullptr), m_SyscallGuard(nullptr), - m_TTYRedirector(nullptr) + m_TTYRedirector(nullptr), + m_FanController(nullptr) { // Hushes error: private field 'm_FileManager' is not used [-Werror,-Wunused-private-field] m_Logger = nullptr; @@ -150,6 +152,15 @@ bool PluginManager::OnLoad() break; } + // Initialize FanController + m_FanController = new Mira::Plugins::FanController(); + if (m_FanController == nullptr) + { + WriteLog(LL_Error, "could not allocate fan controller."); + s_Success = false; + break; + } + // Initialize TTYRedirector m_TTYRedirector = new Mira::Plugins::TTYRedirector(); if (m_TTYRedirector == nullptr) @@ -214,6 +225,12 @@ bool PluginManager::OnLoad() WriteLog(LL_Error, "could not load remote play enabler."); } + if (m_FanController) + { + if (!m_FanController->OnLoad()) + WriteLog(LL_Error, "could not load fan controller."); + } + if (m_TTYRedirector) { if (!m_TTYRedirector->OnLoad()) @@ -376,6 +393,18 @@ bool PluginManager::OnUnload() m_RemotePlayEnabler = nullptr; } + // Delete FanController + if (m_FanController) + { + WriteLog(LL_Debug, "unloading fan controller"); + if (!m_FanController->OnUnload()) + WriteLog(LL_Error, "fan controller could not unload"); + + // Free FanController + delete m_FanController; + m_FanController = nullptr; + } + // Delete the debugger // NOTE: Don't unload before the debugger for catch error if something wrong if (m_Debugger) @@ -483,6 +512,13 @@ bool PluginManager::OnSuspend() WriteLog(LL_Error, "remote play enabler suspend failed"); } + // Suspend FanController (does nothing) + if (m_FanController) + { + if (!m_FanController->OnSuspend()) + WriteLog(LL_Error, "fan controller suspend failed"); + } + // Nota: Don't suspend before the debugger for catch error if something when wrong if (m_Debugger) { @@ -557,6 +593,13 @@ bool PluginManager::OnResume() WriteLog(LL_Error, "remote play enabler resume failed"); } + WriteLog(LL_Debug, "resuming fan controller"); + if (m_FanController) + { + if (!m_FanController->OnResume()) + WriteLog(LL_Error, "fan controller resume failed"); + } + WriteLog(LL_Debug, "resuming tty redirector"); if (m_TTYRedirector) { diff --git a/kernel/src/Plugins/PluginManager.hpp b/kernel/src/Plugins/PluginManager.hpp index 1f4e6aee..06704b40 100644 --- a/kernel/src/Plugins/PluginManager.hpp +++ b/kernel/src/Plugins/PluginManager.hpp @@ -25,11 +25,11 @@ namespace Mira virtual bool OnUnload() override; virtual bool OnSuspend() override; virtual bool OnResume() override; - + virtual bool OnProcessExec(struct proc* p_Process) override; virtual bool OnProcessExecEnd(struct proc* p_Process) override; virtual bool OnProcessExit(struct proc* p_Process) override; - + private: Mira::Utils::IModule* m_Logger; Mira::Utils::IModule* m_Debugger; @@ -43,6 +43,7 @@ namespace Mira Mira::Utils::IModule* m_RemotePlayEnabler; Mira::Utils::IModule* m_SyscallGuard; Mira::Utils::IModule* m_TTYRedirector; + Mira::Utils::IModule* m_FanController; public: Mira::Utils::IModule* GetDebugger() { return m_Debugger; } @@ -53,6 +54,7 @@ namespace Mira Mira::Utils::IModule* GetMorpheusEnabler() { return m_MorpheusEnabler; } Mira::Utils::IModule* GetRemotePlayEnabler() { return m_RemotePlayEnabler; } Mira::Utils::IModule* GetSyscallGuard() { return m_SyscallGuard; } + Mira::Utils::IModule* GetFanController() { return m_FanController; } }; } }