diff --git a/Source/sys-clk/common/include/crc32.h b/Source/sys-clk/common/include/crc32.h new file mode 100644 index 00000000..67539c7d --- /dev/null +++ b/Source/sys-clk/common/include/crc32.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#pragma once +#include +#include + +uint32_t crc32(const uint8_t *data, size_t length) { + uint32_t crc = 0xFFFFFFFF; + + for (size_t i = 0; i < length; i++) { + crc ^= data[i]; + for (int j = 0; j < 8; j++) { + crc = (crc >> 1) ^ (0xEDB88320 & -(crc & 1)); + } + } + return ~crc; +} + +uint32_t checksum_file(const char *filename) { + FILE *file = fopen(filename, "rb"); + if (!file) { + perror("[crc32] Error opening file"); + return 0; + } + + uint8_t buffer[1024]; + uint32_t crc = 0xFFFFFFFF; + size_t bytes_read; + + while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) { + for (size_t i = 0; i < bytes_read; i++) { + crc ^= buffer[i]; + for (int j = 0; j < 8; j++) { + crc = (crc >> 1) ^ (0xEDB88320 & -(crc & 1)); + } + } + } + + fclose(file); + return ~crc; +} \ No newline at end of file diff --git a/Source/sys-clk/common/include/notification.h b/Source/sys-clk/common/include/notification.h index 77c595ca..a6389b6f 100644 --- a/Source/sys-clk/common/include/notification.h +++ b/Source/sys-clk/common/include/notification.h @@ -22,7 +22,7 @@ #include static void writeNotification(const std::string& message) { - const char* flagPath = "sdmc:/config/ultrahand/flags/NOTIFICATIONS.flag"; + static const char* flagPath = "sdmc:/config/ultrahand/flags/NOTIFICATIONS.flag"; FILE* flagFile = fopen(flagPath, "r"); if (!flagFile) { diff --git a/Source/sys-clk/common/include/service_guard.h b/Source/sys-clk/common/include/service_guard.h index d7ce9a7a..96a348a5 100644 --- a/Source/sys-clk/common/include/service_guard.h +++ b/Source/sys-clk/common/include/service_guard.h @@ -1,3 +1,20 @@ +/* + * Copyright (c) MasaGratoR + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + #pragma once #ifdef __cplusplus diff --git a/Source/sys-clk/common/include/sysclk/config.h b/Source/sys-clk/common/include/sysclk/config.h index 79b41765..05a502ab 100644 --- a/Source/sys-clk/common/include/sysclk/config.h +++ b/Source/sys-clk/common/include/sysclk/config.h @@ -158,6 +158,8 @@ typedef enum { KipConfigValue_g_volt_e_1036800, KipConfigValue_g_volt_e_1075200, + KipCrc32, + HocClkConfigValue_IsFirstLoad, SysClkConfigValue_EnumMax, } SysClkConfigValue; @@ -368,7 +370,10 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr case KipConfigValue_g_volt_e_998400: return pretty ? "Erista GPU Volt 998 MHz" : "g_volt_e_998400"; case KipConfigValue_g_volt_e_1036800: return pretty ? "Erista GPU Volt 1036 MHz" : "g_volt_e_1036800"; case KipConfigValue_g_volt_e_1075200: return pretty ? "Erista GPU Volt 1075 MHz" : "g_volt_e_1075200"; - + case KipCrc32: + return pretty ? "CRC32" : "crc32"; + case HocClkConfigValue_IsFirstLoad: + return pretty ? "Is First Load" : "is_first_load"; default: return pretty ? "[cfg] no enum format string" : "err_no_format_string"; } @@ -400,6 +405,7 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val) case HocClkConfigValue_HandheldTDP: case HocClkConfigValue_EnforceBoardLimit: case HocClkConfigValue_FixCpuVoltBug: + case HocClkConfigValue_IsFirstLoad: return 1ULL; case HocClkConfigValue_ThermalThrottleThreshold: return 70ULL; @@ -436,6 +442,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in case HorizonOCConfigValue_OverwriteRefreshRate: case HocClkConfigValue_FixCpuVoltBug: case HorizonOCConfigValue_EnableUnsafeDisplayFreqs: + case HocClkConfigValue_IsFirstLoad: return (input & 0x1) == input; case KipConfigValue_custRev: @@ -527,6 +534,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in case KipConfigValue_g_volt_e_1075200: case KipConfigValue_eristaCpuVmin: case KipConfigValue_eristaCpuUnlock: + case KipCrc32: return true; case HorizonOCConfigValue_BatteryChargeCurrent: return ((input >= 1024) && (input <= 3072)) || !input; diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp index ea9d7216..4f7e9c38 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #define HOSPPC_HAS_BOOST (hosversionAtLeast(7,0,0)) bool isGovernorEnabled = false; // to avoid thread messes @@ -793,6 +794,18 @@ void ClockManager::SetKipData() { FileUtils::LogLine("[clock_manager] Failed to write KIP file"); writeNotification("Horizon OC\nKip write failed"); } + + SysClkConfigValueList configValues; + this->config->GetConfigValues(&configValues); + + configValues.values[KipCrc32] = (u64)checksum_file("sdmc:/atmosphere/kips/hoc.kip"); // write checksum + + if (this->config->SetConfigValues(&configValues, false)) { + FileUtils::LogLine("[clock_manager] Successfully loaded KIP data into config"); + } else { + FileUtils::LogLine("[clock_manager] Warning: Failed to set config values from KIP"); + writeNotification("Horizon OC\nKip config set failed"); + } } // I know this is very hacky, but the config system in the sysmodule doesn't really support writing @@ -812,6 +825,8 @@ void ClockManager::GetKipData() { fclose(fp); } + + SysClkConfigValueList configValues; this->config->GetConfigValues(&configValues); @@ -822,9 +837,21 @@ void ClockManager::GetKipData() { writeNotification("Horizon OC\nKip read failed"); return; } - + + if((u64)checksum_file("sdmc:/atmosphere/kips/hoc.kip") != this->config->GetConfigValue(KipCrc32) && !this->config->GetConfigValue(HocClkConfigValue_IsFirstLoad)) { + SetKipData(); + writeNotification("Horizon OC\nKIP has been updated"); + writeNotification("Horizon OC\nPlease reboot your console"); + writeNotification("Horizon OC\nto complete the update"); + return; + } + if(this->config->GetConfigValue(HocClkConfigValue_IsFirstLoad) == true) { + configValues.values[HocClkConfigValue_IsFirstLoad] = (u64)false; + writeNotification("Horizon OC has been installed"); + } static bool writeBootConfigValues = true; + if(writeBootConfigValues) { writeBootConfigValues = false; @@ -948,32 +975,6 @@ void ClockManager::GetKipData() { } void ClockManager::UpdateRamTimings() { - FILE* fp; - fp = fopen("sdmc:/atmosphere/kips/hoc.kip", "r"); - - if (fp == NULL) { - writeNotification("Horizon OC\nKip opening failed"); - kipAvailable = false; - return; - } else { - kipAvailable = true; - fclose(fp); - } - CustomizeTable table; - - if (!cust_read_and_cache("sdmc:/atmosphere/kips/hoc.kip", &table)) { - FileUtils::LogLine("[clock_manager] Failed to read KIP file for UpdateRamTimings"); - writeNotification("Horizon OC\nKip read failed"); - return; - } - - // if(this->config->GetConfigValue(KipConfigValue_marikoEmcMaxClock) != initialConfigValues[KipConfigValue_marikoEmcMaxClock] || - // this->config->GetConfigValue(KipConfigValue_mem_burst_read_latency) != initialConfigValues[KipConfigValue_mem_burst_read_latency] || - // this->config->GetConfigValue(KipConfigValue_mem_burst_write_latency) != initialConfigValues[KipConfigValue_mem_burst_write_latency] - // ) { - // writeNotification("Horizon OC\nCritical values changed!\nUnable to write timings"); - // return; - // } u32 t1_tRCD = this->config->GetConfigValue(KipConfigValue_t1_tRCD); u32 t2_tRP = this->config->GetConfigValue(KipConfigValue_t2_tRP); u32 t3_tRAS = this->config->GetConfigValue(KipConfigValue_t3_tRAS); diff --git a/dist/atmosphere/kips/hoc.kip b/dist/atmosphere/kips/hoc.kip index 335f1ed2..a34de300 100644 Binary files a/dist/atmosphere/kips/hoc.kip and b/dist/atmosphere/kips/hoc.kip differ