summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2022-02-26 10:41:08 +0100
committerGitHub <noreply@github.com>2022-02-26 10:41:08 +0100
commit20e9501b0d0d18b6b215f2f3ed092a3646267bd1 (patch)
treecd90b946482d00c5431c13b165f28d803cf54f59
parentMerge pull request #7953 from ameerj/radv-rdna2-crash (diff)
parenthle: kernel: KSystemControl: Use 6GB memory layout when "use_extended_memory_layout" setting is enabled. (diff)
downloadyuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.tar
yuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.tar.gz
yuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.tar.bz2
yuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.tar.lz
yuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.tar.xz
yuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.tar.zst
yuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.zip
-rw-r--r--src/common/settings.cpp1
-rw-r--r--src/common/settings.h1
-rw-r--r--src/core/core.cpp11
-rw-r--r--src/core/device_memory.cpp5
-rw-r--r--src/core/device_memory.h4
-rw-r--r--src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp24
-rw-r--r--src/core/hle/kernel/k_event.cpp14
-rw-r--r--src/core/hle/kernel/k_event.h2
-rw-r--r--src/core/hle/kernel/k_process.cpp11
-rw-r--r--src/core/hle/kernel/k_process.h2
-rw-r--r--src/core/hle/kernel/k_resource_limit.cpp19
-rw-r--r--src/core/hle/kernel/k_resource_limit.h3
-rw-r--r--src/core/hle/kernel/kernel.cpp7
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/core/hle/service/kernel_helpers.cpp17
-rw-r--r--src/core/memory.cpp3
-rw-r--r--src/yuzu/configuration/config.cpp2
-rw-r--r--src/yuzu/configuration/configure_general.cpp9
-rw-r--r--src/yuzu/configuration/configure_general.h1
-rw-r--r--src/yuzu/configuration/configure_general.ui7
-rw-r--r--src/yuzu_cmd/config.cpp1
21 files changed, 91 insertions, 55 deletions
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 6964a8273..2810cec15 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -167,6 +167,7 @@ void RestoreGlobalState(bool is_powered_on) {
// Core
values.use_multi_core.SetGlobal(true);
+ values.use_extended_memory_layout.SetGlobal(true);
// CPU
values.cpu_accuracy.SetGlobal(true);
diff --git a/src/common/settings.h b/src/common/settings.h
index 9bee6e10f..d06b23a14 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -466,6 +466,7 @@ struct Values {
// Core
Setting<bool> use_multi_core{true, "use_multi_core"};
+ Setting<bool> use_extended_memory_layout{false, "use_extended_memory_layout"};
// Cpu
RangedSetting<CPUAccuracy> cpu_accuracy{CPUAccuracy::Auto, CPUAccuracy::Auto,
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 3f9a7f44b..b0cfee3ee 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -28,7 +28,9 @@
#include "core/file_sys/vfs_real.h"
#include "core/hardware_interrupt_manager.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_resource_limit.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.h"
@@ -252,9 +254,16 @@ struct System::Impl {
}
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());
ASSERT(Kernel::KProcess::Initialize(main_process, system, "main",
- Kernel::KProcess::ProcessType::Userland)
+ Kernel::KProcess::ProcessType::Userland, resource_limit)
.IsSuccess());
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
if (load_result != Loader::ResultStatus::Success) {
diff --git a/src/core/device_memory.cpp b/src/core/device_memory.cpp
index f19c0515f..e6bc63086 100644
--- a/src/core/device_memory.cpp
+++ b/src/core/device_memory.cpp
@@ -3,10 +3,13 @@
// Refer to the license.txt file included.
#include "core/device_memory.h"
+#include "hle/kernel/board/nintendo/nx/k_system_control.h"
namespace Core {
-DeviceMemory::DeviceMemory() : buffer{DramMemoryMap::Size, 1ULL << 39} {}
+DeviceMemory::DeviceMemory()
+ : buffer{Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize(),
+ 1ULL << 39} {}
DeviceMemory::~DeviceMemory() = default;
} // namespace Core
diff --git a/src/core/device_memory.h b/src/core/device_memory.h
index c4d17705f..daeb551ea 100644
--- a/src/core/device_memory.h
+++ b/src/core/device_memory.h
@@ -12,12 +12,8 @@ namespace Core {
namespace DramMemoryMap {
enum : u64 {
Base = 0x80000000ULL,
- Size = 0x100000000ULL,
- End = Base + Size,
KernelReserveBase = Base + 0x60000,
SlabHeapBase = KernelReserveBase + 0x85000,
- SlapHeapSize = 0xa21000,
- SlabHeapEnd = SlabHeapBase + SlapHeapSize,
};
}; // namespace DramMemoryMap
diff --git a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
index 6f335c251..702cacffc 100644
--- a/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
+++ b/src/core/hle/kernel/board/nintendo/nx/k_system_control.cpp
@@ -5,6 +5,7 @@
#include <random>
#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/secure_monitor.h"
@@ -28,30 +29,13 @@ namespace {
using namespace Common::Literals;
-u32 GetMemoryModeForInit() {
- return 0x01;
-}
-
u32 GetMemorySizeForInit() {
- return 0;
+ return Settings::values.use_extended_memory_layout ? Smc::MemorySize_6GB : Smc::MemorySize_4GB;
}
Smc::MemoryArrangement GetMemoryArrangeForInit() {
- switch (GetMemoryModeForInit() & 0x3F) {
- case 0x01:
- 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;
- }
+ return Settings::values.use_extended_memory_layout ? Smc::MemoryArrangement_6GB
+ : Smc::MemoryArrangement_4GB;
}
} // namespace
diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp
index 0720efece..2e0e8de80 100644
--- a/src/core/hle/kernel/k_event.cpp
+++ b/src/core/hle/kernel/k_event.cpp
@@ -14,7 +14,7 @@ KEvent::KEvent(KernelCore& kernel_)
KEvent::~KEvent() = default;
-void KEvent::Initialize(std::string&& name_) {
+void KEvent::Initialize(std::string&& name_, KProcess* owner_) {
// Increment reference count.
// Because reference count is one on creation, this will result
// 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");
// Set our owner process.
- owner = kernel.CurrentProcess();
- if (owner) {
- owner->Open();
- }
+ owner = owner_;
+ owner->Open();
// Mark initialized.
name = std::move(name_);
@@ -47,10 +45,8 @@ void KEvent::Finalize() {
void KEvent::PostDestroy(uintptr_t arg) {
// Release the event count resource the owner process holds.
KProcess* owner = reinterpret_cast<KProcess*>(arg);
- if (owner) {
- owner->GetResourceLimit()->Release(LimitableResource::Events, 1);
- owner->Close();
- }
+ owner->GetResourceLimit()->Release(LimitableResource::Events, 1);
+ owner->Close();
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h
index 3d3ec99e2..de9732ddf 100644
--- a/src/core/hle/kernel/k_event.h
+++ b/src/core/hle/kernel/k_event.h
@@ -22,7 +22,7 @@ public:
explicit KEvent(KernelCore& kernel_);
~KEvent() override;
- void Initialize(std::string&& name);
+ void Initialize(std::string&& name, KProcess* owner_);
void Finalize() override;
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 85c506979..9233261cd 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -123,12 +123,11 @@ private:
};
ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::string process_name,
- ProcessType type) {
+ ProcessType type, KResourceLimit* res_limit) {
auto& kernel = system.Kernel();
process->name = std::move(process_name);
-
- process->resource_limit = kernel.GetSystemResourceLimit();
+ process->resource_limit = res_limit;
process->status = ProcessStatus::Created;
process->program_id = 0;
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);
- // Open a reference to the resource limit.
- process->resource_limit->Open();
-
// Clear remaining fields.
process->num_running_threads = 0;
process->is_signaled = false;
@@ -153,6 +149,9 @@ ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::st
process->is_suspended = false;
process->schedule_count = 0;
+ // Open a reference to the resource limit.
+ process->resource_limit->Open();
+
return ResultSuccess;
}
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 38b446350..cf1b67428 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -91,7 +91,7 @@ public:
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
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.
KPageTable& PageTable() {
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index 0c4bba66b..a84977c68 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "common/assert.h"
+#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/k_resource_limit.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
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h
index fab6005ff..d23d16aa4 100644
--- a/src/core/hle/kernel/k_resource_limit.h
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -67,4 +67,7 @@ private:
KLightConditionVariable cond_var;
const Core::Timing::CoreTiming* core_timing{};
};
+
+KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size);
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 49c0714ed..797f47021 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -240,13 +240,6 @@ struct KernelCore::Impl {
constexpr u64 secure_applet_memory_size{4_MiB};
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
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) {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 9836809f2..839171e85 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -2332,7 +2332,7 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o
R_UNLESS(event != nullptr, ResultOutOfResource);
// Initialize the event.
- event->Initialize("CreateEvent");
+ event->Initialize("CreateEvent", kernel.CurrentProcess());
// Commit the thread reservation.
event_reservation.Commit();
diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp
index 62f4cdfb2..b8c2c6e51 100644
--- a/src/core/hle/service/kernel_helpers.cpp
+++ b/src/core/hle/service/kernel_helpers.cpp
@@ -3,7 +3,9 @@
// Refer to the license.txt file included.
#include "core/core.h"
+#include "core/core_timing.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_readable_event.h"
#include "core/hle/kernel/k_resource_limit.h"
@@ -15,10 +17,21 @@ namespace Service::KernelHelpers {
ServiceContext::ServiceContext(Core::System& system_, std::string name_)
: 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);
ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_),
- Kernel::KProcess::ProcessType::Userland)
+ Kernel::KProcess::ProcessType::KernelInternal,
+ resource_limit)
.IsSuccess());
+
+ // Close reference to our resource limit, as the process opens one.
+ resource_limit->Close();
}
ServiceContext::~ServiceContext() {
@@ -43,7 +56,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
}
// Initialize the event.
- event->Initialize(std::move(name));
+ event->Initialize(std::move(name), process);
// Commit the thread reservation.
event_reservation.Commit();
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 88d6ec908..28d30eee2 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -39,8 +39,7 @@ struct Memory::Impl {
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((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
- ASSERT_MSG(target >= DramMemoryMap::Base && target < DramMemoryMap::End,
- "Out of bounds target: {:016X}", target);
+ ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}", target);
MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
if (Settings::IsFastmemEnabled()) {
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index d5ba86c03..f915bd856 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -445,6 +445,7 @@ void Config::ReadCoreValues() {
qt_config->beginGroup(QStringLiteral("Core"));
ReadGlobalSetting(Settings::values.use_multi_core);
+ ReadGlobalSetting(Settings::values.use_extended_memory_layout);
qt_config->endGroup();
}
@@ -1019,6 +1020,7 @@ void Config::SaveCoreValues() {
qt_config->beginGroup(QStringLiteral("Core"));
WriteGlobalSetting(Settings::values.use_multi_core);
+ WriteGlobalSetting(Settings::values.use_extended_memory_layout);
qt_config->endGroup();
}
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 978a29fe6..08d5444ec 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -42,6 +42,9 @@ void ConfigureGeneral::SetConfiguration() {
ui->use_multi_core->setEnabled(runtime_lock);
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_user_on_boot->setChecked(UISettings::values.select_user_on_boot.GetValue());
@@ -91,6 +94,9 @@ void ConfigureGeneral::ResetDefaults() {
void ConfigureGeneral::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, ui->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()) {
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);
ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.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]() {
ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h
index 85c1dd4a8..b6f3bb5ed 100644
--- a/src/yuzu/configuration/configure_general.h
+++ b/src/yuzu/configuration/configure_general.h
@@ -48,6 +48,7 @@ private:
ConfigurationShared::CheckState use_speed_limit;
ConfigurationShared::CheckState use_multi_core;
+ ConfigurationShared::CheckState use_extended_memory_layout;
const Core::System& system;
};
diff --git a/src/yuzu/configuration/configure_general.ui b/src/yuzu/configuration/configure_general.ui
index bfc771135..c6ef2ab70 100644
--- a/src/yuzu/configuration/configure_general.ui
+++ b/src/yuzu/configuration/configure_general.ui
@@ -143,6 +143,13 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="use_extended_memory_layout">
+ <property name="text">
+ <string>Extended memory layout (6GB DRAM)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QCheckBox" name="toggle_check_exit">
<property name="text">
<string>Confirm exit while emulation is running</string>
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index ff616da70..30963a8bb 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -266,6 +266,7 @@ void Config::ReadValues() {
// Core
ReadSetting("Core", Settings::values.use_multi_core);
+ ReadSetting("Core", Settings::values.use_extended_memory_layout);
// Cpu
ReadSetting("Cpu", Settings::values.cpu_accuracy);