- Fixed gpu_hz_list typo in governor (#46)
- Parse loader.kip config from { "/", "/atmosphere/", "/atmosphere/kips/", "/bootloader/" } (#44)
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
#include "file_utils.h"
|
||||
#include "clocks.h"
|
||||
#include <dirent.h>
|
||||
#include <filesystem>
|
||||
#include <nxExt.h>
|
||||
|
||||
static LockableMutex g_log_mutex;
|
||||
@@ -182,3 +181,126 @@ void FileUtils::Exit()
|
||||
fsdevUnmountAll();
|
||||
fsExit();
|
||||
}
|
||||
|
||||
void FileUtils::ParseLoaderKip() {
|
||||
const char* dirs[] = { "/", "/atmosphere/", "/atmosphere/kips/", "/bootloader/" };
|
||||
char* full_path = new char[0x200];
|
||||
for (auto const& dir : dirs) {
|
||||
struct dirent *entry = NULL;
|
||||
DIR *dp = opendir(dir);
|
||||
if (!dp)
|
||||
continue;
|
||||
|
||||
while ((entry = readdir(dp))) {
|
||||
if (entry->d_type != DT_REG)
|
||||
continue;
|
||||
|
||||
snprintf(full_path, 0x200, "%s%s", dir, entry->d_name);
|
||||
|
||||
FILE* fp = fopen(full_path, "r");
|
||||
if (!fp)
|
||||
continue;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long res = ftell(fp);
|
||||
fclose(fp);
|
||||
if (res == -1)
|
||||
continue;
|
||||
|
||||
size_t filesize = (size_t)res;
|
||||
if (filesize < 0x1000 || filesize > 512 * 1024)
|
||||
continue;
|
||||
|
||||
const char kip_ext[] = {'.', 'k', 'i', 'p'};
|
||||
size_t file_name_len = strnlen(reinterpret_cast<const char*>(&entry->d_name), 256);
|
||||
const char* file_ext = &entry->d_name[file_name_len - sizeof(kip_ext)];
|
||||
|
||||
if (strncasecmp((const char*)kip_ext, file_ext, sizeof(kip_ext)))
|
||||
continue;
|
||||
|
||||
if (R_SUCCEEDED(CustParser(full_path, filesize))) {
|
||||
LogLine("Parsed cust config from %s, maxMemFreq: %u MHz, boostCpuFreq: %u MHz",
|
||||
full_path,
|
||||
Clocks::maxMemFreq / 1'000'000,
|
||||
Clocks::boostCpuFreq / 1'000'000
|
||||
);
|
||||
delete[] full_path;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] full_path;
|
||||
}
|
||||
|
||||
Result FileUtils::CustParser(const char* filepath, size_t filesize) {
|
||||
enum ParseError {
|
||||
ParseError_Success = 0,
|
||||
ParseError_OpenReadFailed,
|
||||
ParseError_WrongKipMagic,
|
||||
ParseError_CustNotFound,
|
||||
ParseError_WrongCustRev,
|
||||
};
|
||||
|
||||
FILE* fp = fopen(filepath, "r");
|
||||
if (!fp)
|
||||
return ParseError_OpenReadFailed;
|
||||
|
||||
constexpr uint8_t KIP_MAGIC[] = {'K', 'I', 'P', '1', 'L', 'o', 'a', 'd', 'e', 'r'};
|
||||
constexpr size_t BLOCK_SIZE = 0x1000;
|
||||
|
||||
char* tmp_block = new char[BLOCK_SIZE];
|
||||
fread(tmp_block, sizeof(char), BLOCK_SIZE, fp);
|
||||
|
||||
if (memcmp(KIP_MAGIC, tmp_block, sizeof(KIP_MAGIC))) {
|
||||
delete[] tmp_block;
|
||||
return ParseError_WrongKipMagic;
|
||||
}
|
||||
|
||||
CustTable table {};
|
||||
|
||||
fpos_t cust_pos = 0;
|
||||
long block_pos = 0;
|
||||
while ((block_pos = ftell(fp)) >= 0 && (size_t)block_pos < filesize) {
|
||||
for (size_t i = 0; i < BLOCK_SIZE; i += sizeof(table.cust)) {
|
||||
if (memcmp(table.cust, &tmp_block[i], sizeof(table.cust)))
|
||||
continue;
|
||||
|
||||
fgetpos(fp, &cust_pos);
|
||||
cust_pos = cust_pos + i - BLOCK_SIZE;
|
||||
goto found;
|
||||
}
|
||||
fread(tmp_block, sizeof(char), BLOCK_SIZE, fp);
|
||||
}
|
||||
|
||||
found:
|
||||
delete[] tmp_block;
|
||||
|
||||
if (!cust_pos) {
|
||||
fclose(fp);
|
||||
return ParseError_CustNotFound;
|
||||
}
|
||||
|
||||
memset(reinterpret_cast<void*>(&table), 0, sizeof(CustTable));
|
||||
fsetpos(fp, &cust_pos);
|
||||
if (!fread(reinterpret_cast<char*>(&table), 1, sizeof(CustTable), fp)) {
|
||||
fclose(fp);
|
||||
return ParseError_OpenReadFailed;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (table.custRev != 2)
|
||||
return ParseError_WrongCustRev;
|
||||
|
||||
if (Clocks::GetIsMariko()) {
|
||||
if (table.marikoCpuBoostClock)
|
||||
Clocks::boostCpuFreq = table.marikoCpuBoostClock * 1000;
|
||||
if (table.marikoEmcMaxClock)
|
||||
Clocks::maxMemFreq = table.marikoEmcMaxClock * 1000;
|
||||
} else {
|
||||
if (table.eristaEmcMaxClock)
|
||||
Clocks::maxMemFreq = table.eristaEmcMaxClock * 1000;
|
||||
}
|
||||
|
||||
return ParseError_Success;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user