Merge pull request #7932 from bunnei/extended-mem-layout
Add extended memory layout (6GB) support and improve KResourceLimit management
This commit is contained in:
commit
20e9501b0d
21 changed files with 91 additions and 55 deletions
|
@ -167,6 +167,7 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
values.use_multi_core.SetGlobal(true);
|
values.use_multi_core.SetGlobal(true);
|
||||||
|
values.use_extended_memory_layout.SetGlobal(true);
|
||||||
|
|
||||||
// CPU
|
// CPU
|
||||||
values.cpu_accuracy.SetGlobal(true);
|
values.cpu_accuracy.SetGlobal(true);
|
||||||
|
|
|
@ -466,6 +466,7 @@ struct Values {
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
Setting<bool> use_multi_core{true, "use_multi_core"};
|
Setting<bool> use_multi_core{true, "use_multi_core"};
|
||||||
|
Setting<bool> use_extended_memory_layout{false, "use_extended_memory_layout"};
|
||||||
|
|
||||||
// Cpu
|
// Cpu
|
||||||
RangedSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto,
|
RangedSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto,
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
#include "core/file_sys/vfs_real.h"
|
#include "core/file_sys/vfs_real.h"
|
||||||
#include "core/hardware_interrupt_manager.h"
|
#include "core/hardware_interrupt_manager.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
|
#include "core/hle/kernel/k_memory_manager.h"
|
||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
|
#include "core/hle/kernel/k_resource_limit.h"
|
||||||
#include "core/hle/kernel/k_scheduler.h"
|
#include "core/hle/kernel/k_scheduler.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/physical_core.h"
|
#include "core/hle/kernel/physical_core.h"
|
||||||
|
@ -252,9 +254,16 @@ struct System::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
||||||
|
|
||||||
|
// Create a resource limit for the process.
|
||||||
|
const auto physical_memory_size =
|
||||||
|
kernel.MemoryManager().GetSize(Kernel::KMemoryManager::Pool::Application);
|
||||||
|
auto* resource_limit = Kernel::CreateResourceLimitForProcess(system, physical_memory_size);
|
||||||
|
|
||||||
|
// Create the process.
|
||||||
auto main_process = Kernel::KProcess::Create(system.Kernel());
|
auto main_process = Kernel::KProcess::Create(system.Kernel());
|
||||||
ASSERT(Kernel::KProcess::Initialize(main_process, system, "main",
|
ASSERT(Kernel::KProcess::Initialize(main_process, system, "main",
|
||||||
Kernel::KProcess::ProcessType::Userland)
|
Kernel::KProcess::ProcessType::Userland, resource_limit)
|
||||||
.IsSuccess());
|
.IsSuccess());
|
||||||
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
||||||
if (load_result != Loader::ResultStatus::Success) {
|
if (load_result != Loader::ResultStatus::Success) {
|
||||||
|
|
|
@ -3,10 +3,13 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "core/device_memory.h"
|
#include "core/device_memory.h"
|
||||||
|
#include "hle/kernel/board/nintendo/nx/k_system_control.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
DeviceMemory::DeviceMemory() : buffer{DramMemoryMap::Size, 1ULL << 39} {}
|
DeviceMemory::DeviceMemory()
|
||||||
|
: buffer{Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize(),
|
||||||
|
1ULL << 39} {}
|
||||||
DeviceMemory::~DeviceMemory() = default;
|
DeviceMemory::~DeviceMemory() = default;
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
|
@ -12,12 +12,8 @@ namespace Core {
|
||||||
namespace DramMemoryMap {
|
namespace DramMemoryMap {
|
||||||
enum : u64 {
|
enum : u64 {
|
||||||
Base = 0x80000000ULL,
|
Base = 0x80000000ULL,
|
||||||
Size = 0x100000000ULL,
|
|
||||||
End = Base + Size,
|
|
||||||
KernelReserveBase = Base + 0x60000,
|
KernelReserveBase = Base + 0x60000,
|
||||||
SlabHeapBase = KernelReserveBase + 0x85000,
|
SlabHeapBase = KernelReserveBase + 0x85000,
|
||||||
SlapHeapSize = 0xa21000,
|
|
||||||
SlabHeapEnd = SlabHeapBase + SlapHeapSize,
|
|
||||||
};
|
};
|
||||||
}; // namespace DramMemoryMap
|
}; // namespace DramMemoryMap
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
#include "common/literals.h"
|
#include "common/literals.h"
|
||||||
|
#include "common/settings.h"
|
||||||
|
|
||||||
#include "core/hle/kernel/board/nintendo/nx/k_system_control.h"
|
#include "core/hle/kernel/board/nintendo/nx/k_system_control.h"
|
||||||
#include "core/hle/kernel/board/nintendo/nx/secure_monitor.h"
|
#include "core/hle/kernel/board/nintendo/nx/secure_monitor.h"
|
||||||
|
@ -28,30 +29,13 @@ namespace {
|
||||||
|
|
||||||
using namespace Common::Literals;
|
using namespace Common::Literals;
|
||||||
|
|
||||||
u32 GetMemoryModeForInit() {
|
|
||||||
return 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GetMemorySizeForInit() {
|
u32 GetMemorySizeForInit() {
|
||||||
return 0;
|
return Settings::values.use_extended_memory_layout ? Smc::MemorySize_6GB : Smc::MemorySize_4GB;
|
||||||
}
|
}
|
||||||
|
|
||||||
Smc::MemoryArrangement GetMemoryArrangeForInit() {
|
Smc::MemoryArrangement GetMemoryArrangeForInit() {
|
||||||
switch (GetMemoryModeForInit() & 0x3F) {
|
return Settings::values.use_extended_memory_layout ? Smc::MemoryArrangement_6GB
|
||||||
case 0x01:
|
: Smc::MemoryArrangement_4GB;
|
||||||
default:
|
|
||||||
return Smc::MemoryArrangement_4GB;
|
|
||||||
case 0x02:
|
|
||||||
return Smc::MemoryArrangement_4GBForAppletDev;
|
|
||||||
case 0x03:
|
|
||||||
return Smc::MemoryArrangement_4GBForSystemDev;
|
|
||||||
case 0x11:
|
|
||||||
return Smc::MemoryArrangement_6GB;
|
|
||||||
case 0x12:
|
|
||||||
return Smc::MemoryArrangement_6GBForAppletDev;
|
|
||||||
case 0x21:
|
|
||||||
return Smc::MemoryArrangement_8GB;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ KEvent::KEvent(KernelCore& kernel_)
|
||||||
|
|
||||||
KEvent::~KEvent() = default;
|
KEvent::~KEvent() = default;
|
||||||
|
|
||||||
void KEvent::Initialize(std::string&& name_) {
|
void KEvent::Initialize(std::string&& name_, KProcess* owner_) {
|
||||||
// Increment reference count.
|
// Increment reference count.
|
||||||
// Because reference count is one on creation, this will result
|
// Because reference count is one on creation, this will result
|
||||||
// in a reference count of two. Thus, when both readable and
|
// in a reference count of two. Thus, when both readable and
|
||||||
|
@ -30,10 +30,8 @@ void KEvent::Initialize(std::string&& name_) {
|
||||||
writable_event.Initialize(this, name_ + ":Writable");
|
writable_event.Initialize(this, name_ + ":Writable");
|
||||||
|
|
||||||
// Set our owner process.
|
// Set our owner process.
|
||||||
owner = kernel.CurrentProcess();
|
owner = owner_;
|
||||||
if (owner) {
|
|
||||||
owner->Open();
|
owner->Open();
|
||||||
}
|
|
||||||
|
|
||||||
// Mark initialized.
|
// Mark initialized.
|
||||||
name = std::move(name_);
|
name = std::move(name_);
|
||||||
|
@ -47,10 +45,8 @@ void KEvent::Finalize() {
|
||||||
void KEvent::PostDestroy(uintptr_t arg) {
|
void KEvent::PostDestroy(uintptr_t arg) {
|
||||||
// Release the event count resource the owner process holds.
|
// Release the event count resource the owner process holds.
|
||||||
KProcess* owner = reinterpret_cast<KProcess*>(arg);
|
KProcess* owner = reinterpret_cast<KProcess*>(arg);
|
||||||
if (owner) {
|
|
||||||
owner->GetResourceLimit()->Release(LimitableResource::Events, 1);
|
owner->GetResourceLimit()->Release(LimitableResource::Events, 1);
|
||||||
owner->Close();
|
owner->Close();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
explicit KEvent(KernelCore& kernel_);
|
explicit KEvent(KernelCore& kernel_);
|
||||||
~KEvent() override;
|
~KEvent() override;
|
||||||
|
|
||||||
void Initialize(std::string&& name);
|
void Initialize(std::string&& name, KProcess* owner_);
|
||||||
|
|
||||||
void Finalize() override;
|
void Finalize() override;
|
||||||
|
|
||||||
|
|
|
@ -123,12 +123,11 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::string process_name,
|
ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::string process_name,
|
||||||
ProcessType type) {
|
ProcessType type, KResourceLimit* res_limit) {
|
||||||
auto& kernel = system.Kernel();
|
auto& kernel = system.Kernel();
|
||||||
|
|
||||||
process->name = std::move(process_name);
|
process->name = std::move(process_name);
|
||||||
|
process->resource_limit = res_limit;
|
||||||
process->resource_limit = kernel.GetSystemResourceLimit();
|
|
||||||
process->status = ProcessStatus::Created;
|
process->status = ProcessStatus::Created;
|
||||||
process->program_id = 0;
|
process->program_id = 0;
|
||||||
process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
|
process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
|
||||||
|
@ -143,9 +142,6 @@ ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::st
|
||||||
|
|
||||||
kernel.AppendNewProcess(process);
|
kernel.AppendNewProcess(process);
|
||||||
|
|
||||||
// Open a reference to the resource limit.
|
|
||||||
process->resource_limit->Open();
|
|
||||||
|
|
||||||
// Clear remaining fields.
|
// Clear remaining fields.
|
||||||
process->num_running_threads = 0;
|
process->num_running_threads = 0;
|
||||||
process->is_signaled = false;
|
process->is_signaled = false;
|
||||||
|
@ -153,6 +149,9 @@ ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::st
|
||||||
process->is_suspended = false;
|
process->is_suspended = false;
|
||||||
process->schedule_count = 0;
|
process->schedule_count = 0;
|
||||||
|
|
||||||
|
// Open a reference to the resource limit.
|
||||||
|
process->resource_limit->Open();
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ public:
|
||||||
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
||||||
|
|
||||||
static ResultCode Initialize(KProcess* process, Core::System& system, std::string process_name,
|
static ResultCode Initialize(KProcess* process, Core::System& system, std::string process_name,
|
||||||
ProcessType type);
|
ProcessType type, KResourceLimit* res_limit);
|
||||||
|
|
||||||
/// Gets a reference to the process' page table.
|
/// Gets a reference to the process' page table.
|
||||||
KPageTable& PageTable() {
|
KPageTable& PageTable() {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/k_resource_limit.h"
|
#include "core/hle/kernel/k_resource_limit.h"
|
||||||
#include "core/hle/kernel/svc_results.h"
|
#include "core/hle/kernel/svc_results.h"
|
||||||
|
@ -151,4 +152,22 @@ void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size) {
|
||||||
|
auto* resource_limit = KResourceLimit::Create(system.Kernel());
|
||||||
|
resource_limit->Initialize(&system.CoreTiming());
|
||||||
|
|
||||||
|
// Initialize default resource limit values.
|
||||||
|
// TODO(bunnei): These values are the system defaults, the limits for service processes are
|
||||||
|
// lower. These should use the correct limit values.
|
||||||
|
|
||||||
|
ASSERT(resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, physical_memory_size)
|
||||||
|
.IsSuccess());
|
||||||
|
ASSERT(resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess());
|
||||||
|
ASSERT(resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess());
|
||||||
|
ASSERT(resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200).IsSuccess());
|
||||||
|
ASSERT(resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess());
|
||||||
|
|
||||||
|
return resource_limit;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -67,4 +67,7 @@ private:
|
||||||
KLightConditionVariable cond_var;
|
KLightConditionVariable cond_var;
|
||||||
const Core::Timing::CoreTiming* core_timing{};
|
const Core::Timing::CoreTiming* core_timing{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size);
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -240,13 +240,6 @@ struct KernelCore::Impl {
|
||||||
constexpr u64 secure_applet_memory_size{4_MiB};
|
constexpr u64 secure_applet_memory_size{4_MiB};
|
||||||
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
|
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
|
||||||
secure_applet_memory_size));
|
secure_applet_memory_size));
|
||||||
|
|
||||||
// This memory seems to be reserved on hardware, but is not reserved/used by yuzu.
|
|
||||||
// Likely Horizon OS reserved memory
|
|
||||||
// TODO(ameerj): Derive the memory rather than hardcode it.
|
|
||||||
constexpr u64 unknown_reserved_memory{0x2f896000};
|
|
||||||
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
|
|
||||||
unknown_reserved_memory));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializePreemption(KernelCore& kernel) {
|
void InitializePreemption(KernelCore& kernel) {
|
||||||
|
|
|
@ -2332,7 +2332,7 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o
|
||||||
R_UNLESS(event != nullptr, ResultOutOfResource);
|
R_UNLESS(event != nullptr, ResultOutOfResource);
|
||||||
|
|
||||||
// Initialize the event.
|
// Initialize the event.
|
||||||
event->Initialize("CreateEvent");
|
event->Initialize("CreateEvent", kernel.CurrentProcess());
|
||||||
|
|
||||||
// Commit the thread reservation.
|
// Commit the thread reservation.
|
||||||
event_reservation.Commit();
|
event_reservation.Commit();
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/k_event.h"
|
#include "core/hle/kernel/k_event.h"
|
||||||
|
#include "core/hle/kernel/k_memory_manager.h"
|
||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
#include "core/hle/kernel/k_readable_event.h"
|
#include "core/hle/kernel/k_readable_event.h"
|
||||||
#include "core/hle/kernel/k_resource_limit.h"
|
#include "core/hle/kernel/k_resource_limit.h"
|
||||||
|
@ -15,10 +17,21 @@ namespace Service::KernelHelpers {
|
||||||
|
|
||||||
ServiceContext::ServiceContext(Core::System& system_, std::string name_)
|
ServiceContext::ServiceContext(Core::System& system_, std::string name_)
|
||||||
: kernel(system_.Kernel()) {
|
: kernel(system_.Kernel()) {
|
||||||
|
|
||||||
|
// Create a resource limit for the process.
|
||||||
|
const auto physical_memory_size =
|
||||||
|
kernel.MemoryManager().GetSize(Kernel::KMemoryManager::Pool::System);
|
||||||
|
auto* resource_limit = Kernel::CreateResourceLimitForProcess(system_, physical_memory_size);
|
||||||
|
|
||||||
|
// Create the process.
|
||||||
process = Kernel::KProcess::Create(kernel);
|
process = Kernel::KProcess::Create(kernel);
|
||||||
ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_),
|
ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_),
|
||||||
Kernel::KProcess::ProcessType::Userland)
|
Kernel::KProcess::ProcessType::KernelInternal,
|
||||||
|
resource_limit)
|
||||||
.IsSuccess());
|
.IsSuccess());
|
||||||
|
|
||||||
|
// Close reference to our resource limit, as the process opens one.
|
||||||
|
resource_limit->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceContext::~ServiceContext() {
|
ServiceContext::~ServiceContext() {
|
||||||
|
@ -43,7 +56,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the event.
|
// Initialize the event.
|
||||||
event->Initialize(std::move(name));
|
event->Initialize(std::move(name), process);
|
||||||
|
|
||||||
// Commit the thread reservation.
|
// Commit the thread reservation.
|
||||||
event_reservation.Commit();
|
event_reservation.Commit();
|
||||||
|
|
|
@ -39,8 +39,7 @@ struct Memory::Impl {
|
||||||
void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
|
void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
|
||||||
ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
|
ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
|
||||||
ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
|
ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
|
||||||
ASSERT_MSG(target >= DramMemoryMap::Base && target < DramMemoryMap::End,
|
ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}", target);
|
||||||
"Out of bounds target: {:016X}", target);
|
|
||||||
MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
|
MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
|
||||||
|
|
||||||
if (Settings::IsFastmemEnabled()) {
|
if (Settings::IsFastmemEnabled()) {
|
||||||
|
|
|
@ -445,6 +445,7 @@ void Config::ReadCoreValues() {
|
||||||
qt_config->beginGroup(QStringLiteral("Core"));
|
qt_config->beginGroup(QStringLiteral("Core"));
|
||||||
|
|
||||||
ReadGlobalSetting(Settings::values.use_multi_core);
|
ReadGlobalSetting(Settings::values.use_multi_core);
|
||||||
|
ReadGlobalSetting(Settings::values.use_extended_memory_layout);
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
@ -1019,6 +1020,7 @@ void Config::SaveCoreValues() {
|
||||||
qt_config->beginGroup(QStringLiteral("Core"));
|
qt_config->beginGroup(QStringLiteral("Core"));
|
||||||
|
|
||||||
WriteGlobalSetting(Settings::values.use_multi_core);
|
WriteGlobalSetting(Settings::values.use_multi_core);
|
||||||
|
WriteGlobalSetting(Settings::values.use_extended_memory_layout);
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@ void ConfigureGeneral::SetConfiguration() {
|
||||||
|
|
||||||
ui->use_multi_core->setEnabled(runtime_lock);
|
ui->use_multi_core->setEnabled(runtime_lock);
|
||||||
ui->use_multi_core->setChecked(Settings::values.use_multi_core.GetValue());
|
ui->use_multi_core->setChecked(Settings::values.use_multi_core.GetValue());
|
||||||
|
ui->use_extended_memory_layout->setEnabled(runtime_lock);
|
||||||
|
ui->use_extended_memory_layout->setChecked(
|
||||||
|
Settings::values.use_extended_memory_layout.GetValue());
|
||||||
|
|
||||||
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing.GetValue());
|
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing.GetValue());
|
||||||
ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot.GetValue());
|
ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot.GetValue());
|
||||||
|
@ -91,6 +94,9 @@ void ConfigureGeneral::ResetDefaults() {
|
||||||
void ConfigureGeneral::ApplyConfiguration() {
|
void ConfigureGeneral::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, ui->use_multi_core,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, ui->use_multi_core,
|
||||||
use_multi_core);
|
use_multi_core);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_extended_memory_layout,
|
||||||
|
ui->use_extended_memory_layout,
|
||||||
|
use_extended_memory_layout);
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
||||||
|
@ -160,6 +166,9 @@ void ConfigureGeneral::SetupPerGameUI() {
|
||||||
Settings::values.use_speed_limit, use_speed_limit);
|
Settings::values.use_speed_limit, use_speed_limit);
|
||||||
ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core,
|
ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core,
|
||||||
use_multi_core);
|
use_multi_core);
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->use_extended_memory_layout,
|
||||||
|
Settings::values.use_extended_memory_layout,
|
||||||
|
use_extended_memory_layout);
|
||||||
|
|
||||||
connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() {
|
connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() {
|
||||||
ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
|
ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
|
||||||
|
|
|
@ -48,6 +48,7 @@ private:
|
||||||
|
|
||||||
ConfigurationShared::CheckState use_speed_limit;
|
ConfigurationShared::CheckState use_speed_limit;
|
||||||
ConfigurationShared::CheckState use_multi_core;
|
ConfigurationShared::CheckState use_multi_core;
|
||||||
|
ConfigurationShared::CheckState use_extended_memory_layout;
|
||||||
|
|
||||||
const Core::System& system;
|
const Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
|
@ -142,6 +142,13 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="use_extended_memory_layout">
|
||||||
|
<property name="text">
|
||||||
|
<string>Extended memory layout (6GB DRAM)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="toggle_check_exit">
|
<widget class="QCheckBox" name="toggle_check_exit">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|
|
@ -266,6 +266,7 @@ void Config::ReadValues() {
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
ReadSetting("Core", Settings::values.use_multi_core);
|
ReadSetting("Core", Settings::values.use_multi_core);
|
||||||
|
ReadSetting("Core", Settings::values.use_extended_memory_layout);
|
||||||
|
|
||||||
// Cpu
|
// Cpu
|
||||||
ReadSetting("Cpu", Settings::values.cpu_accuracy);
|
ReadSetting("Cpu", Settings::values.cpu_accuracy);
|
||||||
|
|
Loading…
Reference in a new issue