summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2022-02-26 01:41:08 -0800
committerGravatar GitHub2022-02-26 01:41:08 -0800
commit20e9501b0d0d18b6b215f2f3ed092a3646267bd1 (patch)
treecd90b946482d00c5431c13b165f28d803cf54f59 /src/core
parentMerge pull request #7953 from ameerj/radv-rdna2-crash (diff)
parenthle: kernel: KSystemControl: Use 6GB memory layout when "use_extended_memory_... (diff)
downloadyuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.tar.gz
yuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.tar.xz
yuzu-20e9501b0d0d18b6b215f2f3ed092a3646267bd1.zip
Merge pull request #7932 from bunnei/extended-mem-layout
Add extended memory layout (6GB) support and improve KResourceLimit management
Diffstat (limited to 'src/core')
-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
14 files changed, 69 insertions, 55 deletions
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 @@
28#include "core/file_sys/vfs_real.h" 28#include "core/file_sys/vfs_real.h"
29#include "core/hardware_interrupt_manager.h" 29#include "core/hardware_interrupt_manager.h"
30#include "core/hid/hid_core.h" 30#include "core/hid/hid_core.h"
31#include "core/hle/kernel/k_memory_manager.h"
31#include "core/hle/kernel/k_process.h" 32#include "core/hle/kernel/k_process.h"
33#include "core/hle/kernel/k_resource_limit.h"
32#include "core/hle/kernel/k_scheduler.h" 34#include "core/hle/kernel/k_scheduler.h"
33#include "core/hle/kernel/kernel.h" 35#include "core/hle/kernel/kernel.h"
34#include "core/hle/kernel/physical_core.h" 36#include "core/hle/kernel/physical_core.h"
@@ -252,9 +254,16 @@ struct System::Impl {
252 } 254 }
253 255
254 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); 256 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
257
258 // Create a resource limit for the process.
259 const auto physical_memory_size =
260 kernel.MemoryManager().GetSize(Kernel::KMemoryManager::Pool::Application);
261 auto* resource_limit = Kernel::CreateResourceLimitForProcess(system, physical_memory_size);
262
263 // Create the process.
255 auto main_process = Kernel::KProcess::Create(system.Kernel()); 264 auto main_process = Kernel::KProcess::Create(system.Kernel());
256 ASSERT(Kernel::KProcess::Initialize(main_process, system, "main", 265 ASSERT(Kernel::KProcess::Initialize(main_process, system, "main",
257 Kernel::KProcess::ProcessType::Userland) 266 Kernel::KProcess::ProcessType::Userland, resource_limit)
258 .IsSuccess()); 267 .IsSuccess());
259 const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); 268 const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
260 if (load_result != Loader::ResultStatus::Success) { 269 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/device_memory.h" 5#include "core/device_memory.h"
6#include "hle/kernel/board/nintendo/nx/k_system_control.h"
6 7
7namespace Core { 8namespace Core {
8 9
9DeviceMemory::DeviceMemory() : buffer{DramMemoryMap::Size, 1ULL << 39} {} 10DeviceMemory::DeviceMemory()
11 : buffer{Kernel::Board::Nintendo::Nx::KSystemControl::Init::GetIntendedMemorySize(),
12 1ULL << 39} {}
10DeviceMemory::~DeviceMemory() = default; 13DeviceMemory::~DeviceMemory() = default;
11 14
12} // namespace Core 15} // 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 {
12namespace DramMemoryMap { 12namespace DramMemoryMap {
13enum : u64 { 13enum : u64 {
14 Base = 0x80000000ULL, 14 Base = 0x80000000ULL,
15 Size = 0x100000000ULL,
16 End = Base + Size,
17 KernelReserveBase = Base + 0x60000, 15 KernelReserveBase = Base + 0x60000,
18 SlabHeapBase = KernelReserveBase + 0x85000, 16 SlabHeapBase = KernelReserveBase + 0x85000,
19 SlapHeapSize = 0xa21000,
20 SlabHeapEnd = SlabHeapBase + SlapHeapSize,
21}; 17};
22}; // namespace DramMemoryMap 18}; // namespace DramMemoryMap
23 19
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 @@
5#include <random> 5#include <random>
6 6
7#include "common/literals.h" 7#include "common/literals.h"
8#include "common/settings.h"
8 9
9#include "core/hle/kernel/board/nintendo/nx/k_system_control.h" 10#include "core/hle/kernel/board/nintendo/nx/k_system_control.h"
10#include "core/hle/kernel/board/nintendo/nx/secure_monitor.h" 11#include "core/hle/kernel/board/nintendo/nx/secure_monitor.h"
@@ -28,30 +29,13 @@ namespace {
28 29
29using namespace Common::Literals; 30using namespace Common::Literals;
30 31
31u32 GetMemoryModeForInit() {
32 return 0x01;
33}
34
35u32 GetMemorySizeForInit() { 32u32 GetMemorySizeForInit() {
36 return 0; 33 return Settings::values.use_extended_memory_layout ? Smc::MemorySize_6GB : Smc::MemorySize_4GB;
37} 34}
38 35
39Smc::MemoryArrangement GetMemoryArrangeForInit() { 36Smc::MemoryArrangement GetMemoryArrangeForInit() {
40 switch (GetMemoryModeForInit() & 0x3F) { 37 return Settings::values.use_extended_memory_layout ? Smc::MemoryArrangement_6GB
41 case 0x01: 38 : Smc::MemoryArrangement_4GB;
42 default:
43 return Smc::MemoryArrangement_4GB;
44 case 0x02:
45 return Smc::MemoryArrangement_4GBForAppletDev;
46 case 0x03:
47 return Smc::MemoryArrangement_4GBForSystemDev;
48 case 0x11:
49 return Smc::MemoryArrangement_6GB;
50 case 0x12:
51 return Smc::MemoryArrangement_6GBForAppletDev;
52 case 0x21:
53 return Smc::MemoryArrangement_8GB;
54 }
55} 39}
56} // namespace 40} // namespace
57 41
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_)
14 14
15KEvent::~KEvent() = default; 15KEvent::~KEvent() = default;
16 16
17void KEvent::Initialize(std::string&& name_) { 17void KEvent::Initialize(std::string&& name_, KProcess* owner_) {
18 // Increment reference count. 18 // Increment reference count.
19 // Because reference count is one on creation, this will result 19 // Because reference count is one on creation, this will result
20 // in a reference count of two. Thus, when both readable and 20 // in a reference count of two. Thus, when both readable and
@@ -30,10 +30,8 @@ void KEvent::Initialize(std::string&& name_) {
30 writable_event.Initialize(this, name_ + ":Writable"); 30 writable_event.Initialize(this, name_ + ":Writable");
31 31
32 // Set our owner process. 32 // Set our owner process.
33 owner = kernel.CurrentProcess(); 33 owner = owner_;
34 if (owner) { 34 owner->Open();
35 owner->Open();
36 }
37 35
38 // Mark initialized. 36 // Mark initialized.
39 name = std::move(name_); 37 name = std::move(name_);
@@ -47,10 +45,8 @@ void KEvent::Finalize() {
47void KEvent::PostDestroy(uintptr_t arg) { 45void KEvent::PostDestroy(uintptr_t arg) {
48 // Release the event count resource the owner process holds. 46 // Release the event count resource the owner process holds.
49 KProcess* owner = reinterpret_cast<KProcess*>(arg); 47 KProcess* owner = reinterpret_cast<KProcess*>(arg);
50 if (owner) { 48 owner->GetResourceLimit()->Release(LimitableResource::Events, 1);
51 owner->GetResourceLimit()->Release(LimitableResource::Events, 1); 49 owner->Close();
52 owner->Close();
53 }
54} 50}
55 51
56} // namespace Kernel 52} // 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:
22 explicit KEvent(KernelCore& kernel_); 22 explicit KEvent(KernelCore& kernel_);
23 ~KEvent() override; 23 ~KEvent() override;
24 24
25 void Initialize(std::string&& name); 25 void Initialize(std::string&& name, KProcess* owner_);
26 26
27 void Finalize() override; 27 void Finalize() override;
28 28
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:
123}; 123};
124 124
125ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::string process_name, 125ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::string process_name,
126 ProcessType type) { 126 ProcessType type, KResourceLimit* res_limit) {
127 auto& kernel = system.Kernel(); 127 auto& kernel = system.Kernel();
128 128
129 process->name = std::move(process_name); 129 process->name = std::move(process_name);
130 130 process->resource_limit = res_limit;
131 process->resource_limit = kernel.GetSystemResourceLimit();
132 process->status = ProcessStatus::Created; 131 process->status = ProcessStatus::Created;
133 process->program_id = 0; 132 process->program_id = 0;
134 process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() 133 process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
@@ -143,9 +142,6 @@ ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::st
143 142
144 kernel.AppendNewProcess(process); 143 kernel.AppendNewProcess(process);
145 144
146 // Open a reference to the resource limit.
147 process->resource_limit->Open();
148
149 // Clear remaining fields. 145 // Clear remaining fields.
150 process->num_running_threads = 0; 146 process->num_running_threads = 0;
151 process->is_signaled = false; 147 process->is_signaled = false;
@@ -153,6 +149,9 @@ ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::st
153 process->is_suspended = false; 149 process->is_suspended = false;
154 process->schedule_count = 0; 150 process->schedule_count = 0;
155 151
152 // Open a reference to the resource limit.
153 process->resource_limit->Open();
154
156 return ResultSuccess; 155 return ResultSuccess;
157} 156}
158 157
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:
91 static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; 91 static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
92 92
93 static ResultCode Initialize(KProcess* process, Core::System& system, std::string process_name, 93 static ResultCode Initialize(KProcess* process, Core::System& system, std::string process_name,
94 ProcessType type); 94 ProcessType type, KResourceLimit* res_limit);
95 95
96 /// Gets a reference to the process' page table. 96 /// Gets a reference to the process' page table.
97 KPageTable& PageTable() { 97 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6#include "core/core.h"
6#include "core/core_timing.h" 7#include "core/core_timing.h"
7#include "core/hle/kernel/k_resource_limit.h" 8#include "core/hle/kernel/k_resource_limit.h"
8#include "core/hle/kernel/svc_results.h" 9#include "core/hle/kernel/svc_results.h"
@@ -151,4 +152,22 @@ void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) {
151 } 152 }
152} 153}
153 154
155KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size) {
156 auto* resource_limit = KResourceLimit::Create(system.Kernel());
157 resource_limit->Initialize(&system.CoreTiming());
158
159 // Initialize default resource limit values.
160 // TODO(bunnei): These values are the system defaults, the limits for service processes are
161 // lower. These should use the correct limit values.
162
163 ASSERT(resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, physical_memory_size)
164 .IsSuccess());
165 ASSERT(resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess());
166 ASSERT(resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess());
167 ASSERT(resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200).IsSuccess());
168 ASSERT(resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess());
169
170 return resource_limit;
171}
172
154} // namespace Kernel 173} // 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:
67 KLightConditionVariable cond_var; 67 KLightConditionVariable cond_var;
68 const Core::Timing::CoreTiming* core_timing{}; 68 const Core::Timing::CoreTiming* core_timing{};
69}; 69};
70
71KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size);
72
70} // namespace Kernel 73} // 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 {
240 constexpr u64 secure_applet_memory_size{4_MiB}; 240 constexpr u64 secure_applet_memory_size{4_MiB};
241 ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory, 241 ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
242 secure_applet_memory_size)); 242 secure_applet_memory_size));
243
244 // This memory seems to be reserved on hardware, but is not reserved/used by yuzu.
245 // Likely Horizon OS reserved memory
246 // TODO(ameerj): Derive the memory rather than hardcode it.
247 constexpr u64 unknown_reserved_memory{0x2f896000};
248 ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
249 unknown_reserved_memory));
250 } 243 }
251 244
252 void InitializePreemption(KernelCore& kernel) { 245 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
2332 R_UNLESS(event != nullptr, ResultOutOfResource); 2332 R_UNLESS(event != nullptr, ResultOutOfResource);
2333 2333
2334 // Initialize the event. 2334 // Initialize the event.
2335 event->Initialize("CreateEvent"); 2335 event->Initialize("CreateEvent", kernel.CurrentProcess());
2336 2336
2337 // Commit the thread reservation. 2337 // Commit the thread reservation.
2338 event_reservation.Commit(); 2338 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 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/core.h" 5#include "core/core.h"
6#include "core/core_timing.h"
6#include "core/hle/kernel/k_event.h" 7#include "core/hle/kernel/k_event.h"
8#include "core/hle/kernel/k_memory_manager.h"
7#include "core/hle/kernel/k_process.h" 9#include "core/hle/kernel/k_process.h"
8#include "core/hle/kernel/k_readable_event.h" 10#include "core/hle/kernel/k_readable_event.h"
9#include "core/hle/kernel/k_resource_limit.h" 11#include "core/hle/kernel/k_resource_limit.h"
@@ -15,10 +17,21 @@ namespace Service::KernelHelpers {
15 17
16ServiceContext::ServiceContext(Core::System& system_, std::string name_) 18ServiceContext::ServiceContext(Core::System& system_, std::string name_)
17 : kernel(system_.Kernel()) { 19 : kernel(system_.Kernel()) {
20
21 // Create a resource limit for the process.
22 const auto physical_memory_size =
23 kernel.MemoryManager().GetSize(Kernel::KMemoryManager::Pool::System);
24 auto* resource_limit = Kernel::CreateResourceLimitForProcess(system_, physical_memory_size);
25
26 // Create the process.
18 process = Kernel::KProcess::Create(kernel); 27 process = Kernel::KProcess::Create(kernel);
19 ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_), 28 ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_),
20 Kernel::KProcess::ProcessType::Userland) 29 Kernel::KProcess::ProcessType::KernelInternal,
30 resource_limit)
21 .IsSuccess()); 31 .IsSuccess());
32
33 // Close reference to our resource limit, as the process opens one.
34 resource_limit->Close();
22} 35}
23 36
24ServiceContext::~ServiceContext() { 37ServiceContext::~ServiceContext() {
@@ -43,7 +56,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
43 } 56 }
44 57
45 // Initialize the event. 58 // Initialize the event.
46 event->Initialize(std::move(name)); 59 event->Initialize(std::move(name), process);
47 60
48 // Commit the thread reservation. 61 // Commit the thread reservation.
49 event_reservation.Commit(); 62 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 {
39 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) { 39 void MapMemoryRegion(Common::PageTable& page_table, VAddr base, u64 size, PAddr target) {
40 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size); 40 ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: {:016X}", size);
41 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base); 41 ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: {:016X}", base);
42 ASSERT_MSG(target >= DramMemoryMap::Base && target < DramMemoryMap::End, 42 ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}", target);
43 "Out of bounds target: {:016X}", target);
44 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory); 43 MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, Common::PageType::Memory);
45 44
46 if (Settings::IsFastmemEnabled()) { 45 if (Settings::IsFastmemEnabled()) {