mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 16:02:37 +00:00
memory: change defaults
This commit is contained in:
1 parent
9d8c458535
commit
09753bf8ff
7 files changed
+103
-64
No files matched your search
@@ -99,10 +99,6 @@ static void Init(const Config::ConfigOptions& cfg, const std::filesystem::path&
|
||||
|
||||
if (Common::File::IsFileExisting(param_json)) {
|
||||
Loader::SystemContentLoadParamSfo(param_json);
|
||||
if (const auto flexible_memory_size = Loader::SystemContentGetFlexibleMemorySize();
|
||||
flexible_memory_size != 0) {
|
||||
Libs::LibKernel::Memory::SetFlexibleMemorySize(flexible_memory_size);
|
||||
}
|
||||
}
|
||||
if (cfg.splash_enabled) {
|
||||
Libs::Graphics::InitializeSplashScreen(param_json.parent_path());
|
||||
|
||||
@@ -533,16 +533,16 @@ void DrawMemoryAndIo(const Snapshot& shown) {
|
||||
Bytes(guest.pooled_allocated) + " (" + Bytes(guest.pool_committed) + " committed)");
|
||||
Row("Flexible", Bytes(guest.flexible_used) + " / " + Bytes(guest.flexible_total));
|
||||
Row("Extended", Bytes(guest.automatic_allocated));
|
||||
// Past the pool size the guest sees no page-table entries available.
|
||||
const auto entries = std::max(guest.cpu_page_entries, guest.gpu_page_entries);
|
||||
// Past its total a side sees no page-table entries available.
|
||||
const auto percent = std::max(guest.cpu_page_entries * 100 / guest.cpu_page_entries_total,
|
||||
guest.gpu_page_entries * 100 / guest.gpu_page_entries_total);
|
||||
Row("Page table (2 MB)",
|
||||
Fmt("CPU %llu GPU %llu / %llu",
|
||||
Fmt("CPU %llu / %llu GPU %llu / %llu",
|
||||
static_cast<unsigned long long>(guest.cpu_page_entries),
|
||||
static_cast<unsigned long long>(guest.cpu_page_entries_total),
|
||||
static_cast<unsigned long long>(guest.gpu_page_entries),
|
||||
static_cast<unsigned long long>(guest.page_entries_total)),
|
||||
entries > guest.page_entries_total ? BAD
|
||||
: entries * 10 > guest.page_entries_total * 9 ? MEDIUM
|
||||
: GOOD);
|
||||
static_cast<unsigned long long>(guest.gpu_page_entries_total)),
|
||||
LevelColor(static_cast<double>(percent), 90, 100));
|
||||
ImGui::EndTable();
|
||||
}
|
||||
if (BeginSection("Emulator process")) {
|
||||
|
||||
+40
-29
@@ -9,6 +9,7 @@
|
||||
#include "graphics/host_gpu/renderer/renderContext.h"
|
||||
#include "libs/errno.h"
|
||||
#include "libs/libs.h"
|
||||
#include "loader/systemContent.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@@ -63,15 +64,21 @@ constexpr int PROT_GPU_WRITE = 0x20;
|
||||
|
||||
enum class GpuAccessMode { NoAccess, Read, Write, ReadWrite };
|
||||
|
||||
constexpr uint64_t PAGE_TABLE_POOL_SIZE = 4ull * 1024ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t PAGE_TABLE_GRANULARITY = 2ull * 1024ull * 1024ull;
|
||||
constexpr int PAGE_TABLE_POOL_ENTRIES =
|
||||
static_cast<int>(PAGE_TABLE_POOL_SIZE / PAGE_TABLE_GRANULARITY);
|
||||
constexpr uint64_t PAGE_TABLE_GRANULARITY = 2ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t DEFAULT_FLEXIBLE_MEMORY_SIZE = 448ull * 1024ull * 1024ull;
|
||||
// A game gets 12.5 GiB. A fixed 64 MiB cache and mapping table memory past the 64 MiB included
|
||||
// for each of the CPU, GPU and AMM tables come off the top; flexible and direct memory share what
|
||||
// is left. One 4 KiB table maps 2 MiB.
|
||||
constexpr uint64_t GUEST_MEMORY_BUDGET = 12800ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t RESERVED_CACHE_SIZE = 64ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t INCLUDED_TABLE_MEMORY = 64ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t MAPPING_TABLE_SIZE = 4ull * 1024ull;
|
||||
|
||||
static uint64_t g_flexible_memory_size = DEFAULT_FLEXIBLE_MEMORY_SIZE;
|
||||
static bool g_flexible_memory_size_frozen = false;
|
||||
static Graphics::RenderContext* g_gpu_resources = nullptr;
|
||||
static uint64_t g_guest_memory_size = GUEST_MEMORY_BUDGET - RESERVED_CACHE_SIZE;
|
||||
static uint64_t g_flexible_memory_size = DEFAULT_FLEXIBLE_MEMORY_SIZE;
|
||||
static uint64_t g_cpu_table_memory = INCLUDED_TABLE_MEMORY;
|
||||
static uint64_t g_gpu_table_memory = INCLUDED_TABLE_MEMORY;
|
||||
static Graphics::RenderContext* g_gpu_resources = nullptr;
|
||||
#if defined(KYTY_VIRTUAL_MEMORY_ALLOCATION_TESTS)
|
||||
static void (*g_test_gpu_range)(bool, uint64_t, size_t) = nullptr;
|
||||
#endif
|
||||
@@ -664,11 +671,8 @@ public:
|
||||
|
||||
KYTY_CLASS_NO_COPY(PhysicalMemory);
|
||||
|
||||
static constexpr uint64_t TotalSize() { return static_cast<uint64_t>(13824) * 1024 * 1024; }
|
||||
static uint64_t Size() {
|
||||
EXIT_IF(g_flexible_memory_size >= TotalSize());
|
||||
return TotalSize() - g_flexible_memory_size;
|
||||
}
|
||||
static uint64_t TotalSize() { return g_guest_memory_size; }
|
||||
static uint64_t Size() { return TotalSize() - g_flexible_memory_size; }
|
||||
|
||||
bool Alloc(uint64_t search_start, uint64_t search_end, size_t len, size_t alignment,
|
||||
uint64_t* phys_addr_out, int memory_type,
|
||||
@@ -998,7 +1002,22 @@ static bool SelfTestSub64SharedPlaceholderAlias() {
|
||||
static bool ReplaceFixedRangeWithReserved(uint64_t start, uint64_t size);
|
||||
|
||||
void Initialize() {
|
||||
g_flexible_memory_size_frozen = true;
|
||||
const auto params = Loader::SystemContentGetMemoryParams();
|
||||
if (params.flexible_size != 0) {
|
||||
g_flexible_memory_size = params.flexible_size;
|
||||
}
|
||||
g_cpu_table_memory = std::max(params.cpu_table_memory, INCLUDED_TABLE_MEMORY);
|
||||
g_gpu_table_memory = std::max(params.gpu_table_memory, INCLUDED_TABLE_MEMORY);
|
||||
|
||||
const auto table_overhead = g_cpu_table_memory + g_gpu_table_memory +
|
||||
std::max(params.amm_table_memory, INCLUDED_TABLE_MEMORY) -
|
||||
3 * INCLUDED_TABLE_MEMORY;
|
||||
EXIT_IF(g_flexible_memory_size + table_overhead >= GUEST_MEMORY_BUDGET - RESERVED_CACHE_SIZE);
|
||||
g_guest_memory_size = GUEST_MEMORY_BUDGET - RESERVED_CACHE_SIZE - table_overhead;
|
||||
LOGF("\t flexible memory size = %" PRIu64 " MiB, direct memory size = %" PRIu64 " MiB\n",
|
||||
g_flexible_memory_size / (1024ull * 1024ull),
|
||||
(g_guest_memory_size - g_flexible_memory_size) / (1024ull * 1024ull));
|
||||
|
||||
VirtualMemory::Init();
|
||||
g_guest_address_space = std::make_unique<GuestAddressSpace>(PhysicalMemory::TotalSize());
|
||||
g_physical_memory = std::make_unique<PhysicalMemory>();
|
||||
@@ -1066,15 +1085,6 @@ void RegisterCallbacks(callback_func_t alloc_func, callback_func_t free_func) {
|
||||
}
|
||||
}
|
||||
|
||||
void SetFlexibleMemorySize(uint64_t size) {
|
||||
constexpr uint64_t GuestPageSize = 0x4000;
|
||||
EXIT_IF(g_flexible_memory_size_frozen || g_guest_address_space != nullptr);
|
||||
EXIT_IF(size == 0 || (size & (GuestPageSize - 1u)) != 0 || size >= PhysicalMemory::TotalSize());
|
||||
g_flexible_memory_size = size;
|
||||
LOGF("\t flexible memory size = 0x%016" PRIx64 " (%" PRIu64 " MiB)\n", size,
|
||||
size / (1024ull * 1024ull));
|
||||
}
|
||||
|
||||
bool PhysicalMemory::Alloc(uint64_t search_start, uint64_t search_end, size_t len, size_t alignment,
|
||||
uint64_t* phys_addr_out, int memory_type, AllocationKind kind) {
|
||||
if (phys_addr_out == nullptr) {
|
||||
@@ -2655,12 +2665,12 @@ int KYTY_SYSV_ABI KernelGetPageTableStats(int* cpu_total, int* cpu_available, in
|
||||
const auto gpu_used =
|
||||
(g_virtual_ranges != nullptr ? g_virtual_ranges->CountPageTableEntries(true) : 0);
|
||||
|
||||
*cpu_total = PAGE_TABLE_POOL_ENTRIES;
|
||||
*gpu_total = PAGE_TABLE_POOL_ENTRIES;
|
||||
*cpu_available = PAGE_TABLE_POOL_ENTRIES -
|
||||
static_cast<int>(std::min<uint64_t>(cpu_used, PAGE_TABLE_POOL_ENTRIES));
|
||||
*gpu_available = PAGE_TABLE_POOL_ENTRIES -
|
||||
static_cast<int>(std::min<uint64_t>(gpu_used, PAGE_TABLE_POOL_ENTRIES));
|
||||
const auto cpu_tables = g_cpu_table_memory / MAPPING_TABLE_SIZE;
|
||||
const auto gpu_tables = g_gpu_table_memory / MAPPING_TABLE_SIZE;
|
||||
*cpu_total = static_cast<int>(cpu_tables);
|
||||
*gpu_total = static_cast<int>(gpu_tables);
|
||||
*cpu_available = static_cast<int>(cpu_tables - std::min(cpu_used, cpu_tables));
|
||||
*gpu_available = static_cast<int>(gpu_tables - std::min(gpu_used, gpu_tables));
|
||||
|
||||
LOGF_COLOR(Log::Color::Green,
|
||||
"\t cpu_total = %d\n"
|
||||
@@ -4381,7 +4391,8 @@ DebugStats GetDebugStats() {
|
||||
stats.direct_total = PhysicalMemory::Size();
|
||||
stats.flexible_total = FlexibleMemory::Size();
|
||||
stats.pool_committed = g_memory_pool_committed.load(std::memory_order_relaxed);
|
||||
stats.page_entries_total = PAGE_TABLE_POOL_ENTRIES;
|
||||
stats.cpu_page_entries_total = g_cpu_table_memory / MAPPING_TABLE_SIZE;
|
||||
stats.gpu_page_entries_total = g_gpu_table_memory / MAPPING_TABLE_SIZE;
|
||||
if (g_physical_memory != nullptr) {
|
||||
Common::LockGuard lock(g_physical_memory->GetMutex());
|
||||
for (const auto& [start, block]: g_physical_memory->GetPhysicalBlocks()) {
|
||||
|
||||
+4
-4
@@ -26,9 +26,10 @@ struct DebugStats {
|
||||
uint64_t flexible_total = 0;
|
||||
uint64_t flexible_used = 0;
|
||||
uint64_t pool_committed = 0;
|
||||
uint64_t cpu_page_entries = 0; // 2 MiB page-table entries in use.
|
||||
uint64_t gpu_page_entries = 0;
|
||||
uint64_t page_entries_total = 0; // Per side.
|
||||
uint64_t cpu_page_entries = 0; // 2 MiB page-table entries in use.
|
||||
uint64_t gpu_page_entries = 0;
|
||||
uint64_t cpu_page_entries_total = 0;
|
||||
uint64_t gpu_page_entries_total = 0;
|
||||
};
|
||||
[[nodiscard]] DebugStats GetDebugStats();
|
||||
|
||||
@@ -125,7 +126,6 @@ static_assert(sizeof(KernelMemoryPoolBlockStats) == 16,
|
||||
"KernelMemoryPoolBlockStats struct size is incorrect");
|
||||
|
||||
void RegisterCallbacks(callback_func_t alloc_func, callback_func_t free_func);
|
||||
void SetFlexibleMemorySize(uint64_t size);
|
||||
int AllocateDirectMemory(int64_t search_start, int64_t search_end, size_t size, size_t alignment,
|
||||
int memory_type, int64_t* phys_addr_out, bool automatic = false);
|
||||
int MapAutomaticMemory(uint64_t vaddr, size_t size, int type, int prot);
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
bool GetParamInt(const char* name, int32_t* value);
|
||||
bool GetParamString(const char* name, std::string* value);
|
||||
bool GetParamString(const char* name, char* value, size_t value_size);
|
||||
uint64_t GetFlexibleMemorySize();
|
||||
MemoryParams GetMemoryParams();
|
||||
|
||||
void DbgPrint();
|
||||
|
||||
@@ -61,7 +61,7 @@ private:
|
||||
Common::Mutex m_mutex;
|
||||
bool m_opened = false;
|
||||
std::vector<Param> m_params;
|
||||
uint64_t m_flexible_memory_size = 0;
|
||||
MemoryParams m_memory_params;
|
||||
};
|
||||
|
||||
class PlayGo {
|
||||
@@ -172,11 +172,21 @@ void Psf::OpenJson(const std::filesystem::path& file_name) {
|
||||
add_int_param("userDefinedParam3", "USER_DEFINED_PARAM_3");
|
||||
add_int_param("userDefinedParam4", "USER_DEFINED_PARAM_4");
|
||||
|
||||
auto read_size = [](const nlohmann::ordered_json& object, const char* key, uint64_t* size,
|
||||
uint64_t unit = 1) {
|
||||
if (auto it = object.find(key); it != object.end()) {
|
||||
*size = it->get<uint64_t>() * unit;
|
||||
}
|
||||
};
|
||||
if (auto kernel = param_json.find("kernel");
|
||||
kernel != param_json.end() && kernel->is_object()) {
|
||||
if (auto it = kernel->find("flexibleMemorySize"); it != kernel->end()) {
|
||||
m_flexible_memory_size = it->get<uint64_t>();
|
||||
}
|
||||
read_size(*kernel, "flexibleMemorySize", &m_memory_params.flexible_size);
|
||||
read_size(*kernel, "cpuPageTableSize", &m_memory_params.cpu_table_memory);
|
||||
read_size(*kernel, "gpuPageTableSize", &m_memory_params.gpu_table_memory);
|
||||
}
|
||||
if (auto amm = param_json.find("amm"); amm != param_json.end() && amm->is_object()) {
|
||||
read_size(*amm, "pagetableMemorySizeInMib", &m_memory_params.amm_table_memory,
|
||||
1024ull * 1024ull);
|
||||
}
|
||||
|
||||
auto localized = param_json.find("localizedParameters");
|
||||
@@ -227,8 +237,8 @@ void Psf::Close() {
|
||||
Common::LockGuard lock(m_mutex);
|
||||
|
||||
m_params.clear();
|
||||
m_flexible_memory_size = 0;
|
||||
m_opened = false;
|
||||
m_memory_params = {};
|
||||
m_opened = false;
|
||||
}
|
||||
|
||||
bool Psf::IsValid() {
|
||||
@@ -339,10 +349,10 @@ bool Psf::GetParamString(const char* name, char* value, size_t value_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t Psf::GetFlexibleMemorySize() {
|
||||
MemoryParams Psf::GetMemoryParams() {
|
||||
Common::LockGuard lock(m_mutex);
|
||||
|
||||
return m_flexible_memory_size;
|
||||
return m_memory_params;
|
||||
}
|
||||
|
||||
PlayGo::~PlayGo() {
|
||||
@@ -646,10 +656,10 @@ bool SystemContentParamSfoGetString(const char* name, char* value, size_t value_
|
||||
return sc->psf.GetParamString(name, value, value_size);
|
||||
}
|
||||
|
||||
uint64_t SystemContentGetFlexibleMemorySize() {
|
||||
MemoryParams SystemContentGetMemoryParams() {
|
||||
auto* sc = Common::Singleton<SystemContent>::Instance();
|
||||
|
||||
return sc->psf.GetFlexibleMemorySize();
|
||||
return sc->psf.GetMemoryParams();
|
||||
}
|
||||
|
||||
bool SystemContentGetIconPath(std::filesystem::path* path) {
|
||||
|
||||
@@ -14,7 +14,16 @@ void SystemContentLoadParamSfo(const std::filesystem::path& file_name);
|
||||
bool SystemContentParamSfoGetInt(const char* name, int32_t* value);
|
||||
bool SystemContentParamSfoGetString(const char* name, std::string* value);
|
||||
bool SystemContentParamSfoGetString(const char* name, char* value, size_t value_size);
|
||||
uint64_t SystemContentGetFlexibleMemorySize();
|
||||
// Memory sizes a game's param.json sets, in bytes; 0 where it sets none.
|
||||
struct MemoryParams {
|
||||
uint64_t flexible_size = 0;
|
||||
uint64_t cpu_table_memory = 0;
|
||||
uint64_t gpu_table_memory = 0;
|
||||
uint64_t amm_table_memory = 0;
|
||||
};
|
||||
|
||||
MemoryParams SystemContentGetMemoryParams();
|
||||
|
||||
bool SystemContentGetIconPath(std::filesystem::path* path);
|
||||
bool SystemContentGetChunksNum(uint32_t* num);
|
||||
|
||||
|
||||
@@ -88,9 +88,14 @@ using Libs::LibKernel::Memory::VirtualQueryInfo;
|
||||
|
||||
// Prospero ABI?
|
||||
constexpr uint64_t SceKernelPageSize = 0x4000;
|
||||
constexpr uint64_t SceKernelTotalPhysicalSize = 13824ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t SceKernelFlexibleMemorySize = 448ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t TestFlexibleMemorySize = 3072ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t GuestMemoryBudget = 12800ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t ReservedCacheSize = 64ull * 1024ull * 1024ull;
|
||||
// The 128 MiB CPU and 96 MiB AMM mapping tables add 64 + 32 MiB; a zero GPU table size adds none.
|
||||
constexpr uint64_t TestCpuTableMemory = 128ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t TestAmmTableMemory = 96ull * 1024ull * 1024ull;
|
||||
constexpr uint64_t TestTableOverhead = 96ull * 1024ull * 1024ull;
|
||||
constexpr int SceKernelProtCpuRead = 0x01;
|
||||
constexpr int SceKernelProtCpuRw = 0x02;
|
||||
constexpr int SceKernelProtCpuExec = 0x04;
|
||||
@@ -175,7 +180,9 @@ void InitSubsystems() {
|
||||
const auto param_json = std::filesystem::temp_directory_path() /
|
||||
("kyty_virtual_memory_" +
|
||||
std::to_string(reinterpret_cast<uintptr_t>(&initialized)) + ".json");
|
||||
constexpr char json[] = R"({"kernel":{"flexibleMemorySize":3221225472}})";
|
||||
constexpr char json[] =
|
||||
R"({"kernel":{"flexibleMemorySize":3221225472,"cpuPageTableSize":134217728,)"
|
||||
R"("gpuPageTableSize":0},"amm":{"pagetableMemorySizeInMib":96}})";
|
||||
Common::File param_file;
|
||||
Check("InitSubsystems", param_file.Create(param_json), "failed to create temporary param.json");
|
||||
uint32_t bytes_written = 0;
|
||||
@@ -185,16 +192,19 @@ void InitSubsystems() {
|
||||
"failed to write temporary param.json");
|
||||
|
||||
Loader::SystemContentLoadParamSfo(param_json);
|
||||
const auto flexible_memory_size = Loader::SystemContentGetFlexibleMemorySize();
|
||||
const auto params = Loader::SystemContentGetMemoryParams();
|
||||
Check("InitSubsystems", Common::File::DeleteFile(param_json),
|
||||
"failed to remove temporary param.json");
|
||||
Check("InitSubsystems", flexible_memory_size == TestFlexibleMemorySize,
|
||||
Check("InitSubsystems", params.flexible_size == TestFlexibleMemorySize,
|
||||
"failed to read flexible memory size from param.json");
|
||||
Check("InitSubsystems",
|
||||
params.cpu_table_memory == TestCpuTableMemory && params.gpu_table_memory == 0 &&
|
||||
params.amm_table_memory == TestAmmTableMemory,
|
||||
"failed to read mapping table sizes from param.json");
|
||||
size_t default_flexible_memory_size = 0;
|
||||
Libs::LibKernel::Memory::KernelConfiguredFlexibleMemorySize(&default_flexible_memory_size);
|
||||
Check("InitSubsystems", default_flexible_memory_size == SceKernelFlexibleMemorySize,
|
||||
"flexible memory does not default to 448 MiB without param.json");
|
||||
Libs::LibKernel::Memory::SetFlexibleMemorySize(flexible_memory_size);
|
||||
|
||||
subsystems.Initialize<Libs::LibKernel::Memory::Lifecycle>();
|
||||
|
||||
@@ -822,8 +832,8 @@ void TestFlexibleMemoryCapacityIsBootFixed() {
|
||||
Check(test, configured == TestFlexibleMemorySize,
|
||||
"boot flexible pool did not use the param.json value");
|
||||
Check(test, configured == baseline, "boot flexible pool did not start at configured capacity");
|
||||
Check(test, backing == SceKernelTotalPhysicalSize,
|
||||
"boot backing is not the single 13.5 GiB physical file");
|
||||
Check(test, backing == GuestMemoryBudget - ReservedCacheSize - TestTableOverhead,
|
||||
"boot backing is not the 12.5 GiB budget less the reserved cache and table overhead");
|
||||
Check(test, backing == Libs::LibKernel::Memory::KernelGetDirectMemorySize() + configured,
|
||||
"direct and flexible regions do not partition the boot backing");
|
||||
|
||||
@@ -1409,7 +1419,10 @@ void TestPageTableStatsTrackRangeEdits() {
|
||||
"KernelGetPageTableStats");
|
||||
return stats;
|
||||
};
|
||||
const auto baseline = read_stats();
|
||||
// A 4 KiB table maps 2 MiB: 128 MiB of CPU tables gives 32768, the default 64 MiB GPU 16384.
|
||||
const auto baseline = read_stats();
|
||||
Check(test, baseline[0] == 32768 && baseline[2] == 16384,
|
||||
"page-table totals do not follow the configured table memory");
|
||||
const auto expect_used = [&](int cpu, int gpu, const char* action) {
|
||||
const auto stats = read_stats();
|
||||
Check(test,
|
||||
|
||||
Reference in new issue
Block a user