summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/k_resource_limit.cpp13
-rw-r--r--src/core/hle/kernel/k_resource_limit.h12
-rw-r--r--src/core/hle/kernel/kernel.cpp44
-rw-r--r--src/core/hle/kernel/process.cpp24
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/video_core/engines/engine_interface.h3
-rw-r--r--src/video_core/engines/fermi_2d.h2
-rw-r--r--src/video_core/engines/kepler_memory.h2
-rw-r--r--src/video_core/engines/maxwell_dma.h2
-rw-r--r--src/yuzu/applets/controller.cpp16
-rw-r--r--src/yuzu/applets/controller.h3
11 files changed, 62 insertions, 61 deletions
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp
index d7a4a38e6..d05b34ea3 100644
--- a/src/core/hle/kernel/k_resource_limit.cpp
+++ b/src/core/hle/kernel/k_resource_limit.cpp
@@ -2,21 +2,16 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-// This file references various implementation details from Atmosphere, an open-source firmware for
-// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
-
#include "common/assert.h"
-#include "core/core.h"
#include "core/core_timing.h"
-#include "core/core_timing_util.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel {
constexpr s64 DefaultTimeout = 10000000000; // 10 seconds
-KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system)
- : Object{kernel}, lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {}
+KResourceLimit::KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_)
+ : Object{kernel}, lock{kernel}, cond_var{kernel}, core_timing(core_timing_) {}
KResourceLimit::~KResourceLimit() = default;
s64 KResourceLimit::GetLimitValue(LimitableResource which) const {
@@ -83,7 +78,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
}
bool KResourceLimit::Reserve(LimitableResource which, s64 value) {
- return Reserve(which, value, system.CoreTiming().GetGlobalTimeNs().count() + DefaultTimeout);
+ return Reserve(which, value, core_timing.GetGlobalTimeNs().count() + DefaultTimeout);
}
bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
@@ -114,7 +109,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) {
}
if (current_hints[index] + value <= limit_values[index] &&
- (timeout < 0 || system.CoreTiming().GetGlobalTimeNs().count() < timeout)) {
+ (timeout < 0 || core_timing.GetGlobalTimeNs().count() < timeout)) {
waiter_count++;
cond_var.Wait(&lock, timeout);
waiter_count--;
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h
index 58ae456f1..4542317d0 100644
--- a/src/core/hle/kernel/k_resource_limit.h
+++ b/src/core/hle/kernel/k_resource_limit.h
@@ -2,9 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-// This file references various implementation details from Atmosphere, an open-source firmware for
-// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
-
#pragma once
#include <array>
@@ -15,8 +12,8 @@
union ResultCode;
-namespace Core {
-class System;
+namespace Core::Timing {
+class CoreTiming;
}
namespace Kernel {
@@ -37,7 +34,7 @@ constexpr bool IsValidResourceType(LimitableResource type) {
class KResourceLimit final : public Object {
public:
- explicit KResourceLimit(KernelCore& kernel, Core::System& system);
+ explicit KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_);
~KResourceLimit();
s64 GetLimitValue(LimitableResource which) const;
@@ -75,7 +72,6 @@ private:
mutable KLightLock lock;
s32 waiter_count{};
KLightConditionVariable cond_var;
- KernelCore& kernel;
- Core::System& system;
+ const Core::Timing::CoreTiming& core_timing;
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 8fd990577..5c4f45ab4 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -67,8 +67,13 @@ struct KernelCore::Impl {
is_phantom_mode_for_singlecore = false;
InitializePhysicalCores();
- InitializeSystemResourceLimit(kernel, system);
- InitializeMemoryLayout();
+
+ // Derive the initial memory layout from the emulated board
+ KMemoryLayout memory_layout;
+ DeriveInitialMemoryLayout(memory_layout);
+ InitializeMemoryLayout(memory_layout);
+ InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout);
+ InitializeSlabHeaps();
InitializeSchedulers();
InitializeSuspendThreads();
InitializePreemption(kernel);
@@ -137,27 +142,33 @@ struct KernelCore::Impl {
}
// Creates the default system resource limit
- void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) {
- system_resource_limit = std::make_shared<KResourceLimit>(kernel, system);
+ void InitializeSystemResourceLimit(KernelCore& kernel,
+ const Core::Timing::CoreTiming& core_timing,
+ const KMemoryLayout& memory_layout) {
+ system_resource_limit = std::make_shared<KResourceLimit>(kernel, core_timing);
+ const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes();
// If setting the default system values fails, then something seriously wrong has occurred.
- ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000)
+ ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size)
.IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200)
.IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess());
+ system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size);
- // Derived from recent software updates. The kernel reserves 27MB
- constexpr u64 kernel_size{0x1b00000};
- if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size)) {
- UNREACHABLE();
- }
// Reserve secure applet memory, introduced in firmware 5.0.0
- constexpr u64 secure_applet_memory_size{0x400000};
+ constexpr u64 secure_applet_memory_size{Common::Size_4_MB};
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) {
@@ -531,11 +542,7 @@ struct KernelCore::Impl {
linear_region_start);
}
- void InitializeMemoryLayout() {
- // Derive the initial memory layout from the emulated board
- KMemoryLayout memory_layout;
- DeriveInitialMemoryLayout(memory_layout);
-
+ void InitializeMemoryLayout(const KMemoryLayout& memory_layout) {
const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents();
const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents();
const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents();
@@ -578,11 +585,14 @@ struct KernelCore::Impl {
system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size,
"Time:SharedMemory");
+ }
+ void InitializeSlabHeaps() {
// Allocate slab heaps
user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>();
- constexpr u64 user_slab_heap_size{0x1ef000};
+ // TODO(ameerj): This should be derived, not hardcoded within the kernel
+ constexpr u64 user_slab_heap_size{0x3de000};
// Reserve slab heaps
ASSERT(
system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size));
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 420888439..e35deb8e2 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -120,9 +120,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
std::shared_ptr<Process> process = std::make_shared<Process>(system);
process->name = std::move(name);
- // TODO: This is inaccurate
- // The process should hold a reference to the kernel-wide resource limit.
- process->resource_limit = std::make_shared<KResourceLimit>(kernel, system);
+ process->resource_limit = kernel.GetSystemResourceLimit();
process->status = ProcessStatus::Created;
process->program_id = 0;
process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
@@ -160,17 +158,13 @@ void Process::DecrementThreadCount() {
}
u64 Process::GetTotalPhysicalMemoryAvailable() const {
- // TODO: This is expected to always return the application memory pool size after accurately
- // reserving kernel resources. The current workaround uses a process-local resource limit of
- // application memory pool size, which is inaccurate.
const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) +
page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
main_thread_stack_size};
-
+ ASSERT(capacity == kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
if (capacity < memory_usage_capacity) {
return capacity;
}
-
return memory_usage_capacity;
}
@@ -272,10 +266,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
system_resource_size = metadata.GetSystemResourceSize();
image_size = code_size;
- // Set initial resource limits
- resource_limit->SetLimitValue(
- LimitableResource::PhysicalMemory,
- kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
code_size + system_resource_size);
if (!memory_reservation.Succeeded()) {
@@ -324,16 +314,6 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
UNREACHABLE();
}
- // Set initial resource limits
- resource_limit->SetLimitValue(
- LimitableResource::PhysicalMemory,
- kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
-
- resource_limit->SetLimitValue(LimitableResource::Threads, 608);
- resource_limit->SetLimitValue(LimitableResource::Events, 700);
- resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128);
- resource_limit->SetLimitValue(LimitableResource::Sessions, 894);
-
// Create TLS region
tls_region_address = CreateTLSRegion();
memory_reservation.Commit();
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index fcffc746d..bebb86154 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -2156,7 +2156,7 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle)
LOG_DEBUG(Kernel_SVC, "called");
auto& kernel = system.Kernel();
- auto resource_limit = std::make_shared<KResourceLimit>(kernel, system);
+ auto resource_limit = std::make_shared<KResourceLimit>(kernel, system.CoreTiming());
auto* const current_process = kernel.CurrentProcess();
ASSERT(current_process != nullptr);
diff --git a/src/video_core/engines/engine_interface.h b/src/video_core/engines/engine_interface.h
index 18a9db7e6..c7ffd68c5 100644
--- a/src/video_core/engines/engine_interface.h
+++ b/src/video_core/engines/engine_interface.h
@@ -4,13 +4,14 @@
#pragma once
-#include <type_traits>
#include "common/common_types.h"
namespace Tegra::Engines {
class EngineInterface {
public:
+ virtual ~EngineInterface() = default;
+
/// Write the value to the register identified by method.
virtual void CallMethod(u32 method, u32 method_argument, bool is_last_call) = 0;
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h
index c808a577d..a4170ffff 100644
--- a/src/video_core/engines/fermi_2d.h
+++ b/src/video_core/engines/fermi_2d.h
@@ -35,7 +35,7 @@ namespace Tegra::Engines {
class Fermi2D final : public EngineInterface {
public:
explicit Fermi2D();
- ~Fermi2D();
+ ~Fermi2D() override;
/// Binds a rasterizer to this engine.
void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h
index 19808a5c6..0d8ea09a9 100644
--- a/src/video_core/engines/kepler_memory.h
+++ b/src/video_core/engines/kepler_memory.h
@@ -36,7 +36,7 @@ namespace Tegra::Engines {
class KeplerMemory final : public EngineInterface {
public:
explicit KeplerMemory(Core::System& system_, MemoryManager& memory_manager);
- ~KeplerMemory();
+ ~KeplerMemory() override;
/// Write the value to the register identified by method.
void CallMethod(u32 method, u32 method_argument, bool is_last_call) override;
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h
index 3c59eeb13..c77f02a22 100644
--- a/src/video_core/engines/maxwell_dma.h
+++ b/src/video_core/engines/maxwell_dma.h
@@ -188,7 +188,7 @@ public:
static_assert(sizeof(RemapConst) == 12);
explicit MaxwellDMA(Core::System& system_, MemoryManager& memory_manager_);
- ~MaxwellDMA();
+ ~MaxwellDMA() override;
/// Write the value to the register identified by method.
void CallMethod(u32 method, u32 method_argument, bool is_last_call) override;
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index b92cd6886..836d90fda 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -16,6 +16,7 @@
#include "yuzu/applets/controller.h"
#include "yuzu/configuration/configure_input.h"
#include "yuzu/configuration/configure_input_profile_dialog.h"
+#include "yuzu/configuration/configure_motion_touch.h"
#include "yuzu/configuration/configure_vibration.h"
#include "yuzu/configuration/input_profiles.h"
#include "yuzu/main.h"
@@ -206,6 +207,9 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
connect(ui->vibrationButton, &QPushButton::clicked, this,
&QtControllerSelectorDialog::CallConfigureVibrationDialog);
+ connect(ui->motionButton, &QPushButton::clicked, this,
+ &QtControllerSelectorDialog::CallConfigureMotionTouchDialog);
+
connect(ui->inputConfigButton, &QPushButton::clicked, this,
&QtControllerSelectorDialog::CallConfigureInputProfileDialog);
@@ -276,6 +280,18 @@ void QtControllerSelectorDialog::CallConfigureVibrationDialog() {
}
}
+void QtControllerSelectorDialog::CallConfigureMotionTouchDialog() {
+ ConfigureMotionTouch dialog(this, input_subsystem);
+
+ dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
+ Qt::WindowSystemMenuHint);
+ dialog.setWindowModality(Qt::WindowModal);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ dialog.ApplyConfiguration();
+ }
+}
+
void QtControllerSelectorDialog::CallConfigureInputProfileDialog() {
ConfigureInputProfileDialog dialog(this, input_subsystem, input_profiles.get());
diff --git a/src/yuzu/applets/controller.h b/src/yuzu/applets/controller.h
index 3518eed56..9b57aea1a 100644
--- a/src/yuzu/applets/controller.h
+++ b/src/yuzu/applets/controller.h
@@ -51,6 +51,9 @@ private:
// Initializes the "Configure Vibration" Dialog.
void CallConfigureVibrationDialog();
+ // Initializes the "Configure Motion / Touch" Dialog.
+ void CallConfigureMotionTouchDialog();
+
// Initializes the "Create Input Profile" Dialog.
void CallConfigureInputProfileDialog();