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
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue