summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar Subv2015-05-12 15:25:15 -0500
committerGravatar Subv2015-05-14 22:50:13 -0500
commitd3634d4bf4b1cbd8cc4fe6f22178054803b41e23 (patch)
tree2fa606ebac3e2e77e65e1196878a5f5345acfacf /src/core/hle/kernel
parentMerge pull request #762 from yuriks/memmap (diff)
downloadyuzu-d3634d4bf4b1cbd8cc4fe6f22178054803b41e23.tar.gz
yuzu-d3634d4bf4b1cbd8cc4fe6f22178054803b41e23.tar.xz
yuzu-d3634d4bf4b1cbd8cc4fe6f22178054803b41e23.zip
Core/ResourceLimits: Implemented the basic structure of ResourceLimits.
Implemented svcs GetResourceLimit, GetResourceLimitCurrentValues and GetResourceLimitLimitValues. Note that the resource limits do not currently keep track of used objects, since we have no way to distinguish between an object created by the application, and an object created by some HLE module once we're inside Kernel::T::Create.
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/kernel.cpp3
-rw-r--r--src/core/hle/kernel/kernel.h3
-rw-r--r--src/core/hle/kernel/process.cpp1
-rw-r--r--src/core/hle/kernel/process.h4
-rw-r--r--src/core/hle/kernel/resource_limit.cpp157
-rw-r--r--src/core/hle/kernel/resource_limit.h119
6 files changed, 286 insertions, 1 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index b5c98b249..726e4d2ff 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -10,6 +10,7 @@
10#include "core/arm/arm_interface.h" 10#include "core/arm/arm_interface.h"
11#include "core/core.h" 11#include "core/core.h"
12#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/resource_limit.h"
13#include "core/hle/kernel/process.h" 14#include "core/hle/kernel/process.h"
14#include "core/hle/kernel/thread.h" 15#include "core/hle/kernel/thread.h"
15#include "core/hle/kernel/timer.h" 16#include "core/hle/kernel/timer.h"
@@ -134,6 +135,7 @@ void HandleTable::Clear() {
134 135
135/// Initialize the kernel 136/// Initialize the kernel
136void Init() { 137void Init() {
138 Kernel::ResourceLimitsInit();
137 Kernel::ThreadingInit(); 139 Kernel::ThreadingInit();
138 Kernel::TimersInit(); 140 Kernel::TimersInit();
139 141
@@ -147,6 +149,7 @@ void Init() {
147void Shutdown() { 149void Shutdown() {
148 Kernel::ThreadingShutdown(); 150 Kernel::ThreadingShutdown();
149 Kernel::TimersShutdown(); 151 Kernel::TimersShutdown();
152 Kernel::ResourceLimitsShutdown();
150 g_handle_table.Clear(); // Free all kernel objects 153 g_handle_table.Clear(); // Free all kernel objects
151 g_current_process = nullptr; 154 g_current_process = nullptr;
152} 155}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 7c106d37c..28748c8f5 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -46,7 +46,8 @@ enum class HandleType : u32 {
46 Process = 8, 46 Process = 8,
47 AddressArbiter = 9, 47 AddressArbiter = 9,
48 Semaphore = 10, 48 Semaphore = 10,
49 Timer = 11 49 Timer = 11,
50 ResourceLimit = 12,
50}; 51};
51 52
52enum { 53enum {
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 0cdfa58d7..b5c87e883 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -7,6 +7,7 @@
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8 8
9#include "core/hle/kernel/process.h" 9#include "core/hle/kernel/process.h"
10#include "core/hle/kernel/resource_limit.h"
10#include "core/hle/kernel/thread.h" 11#include "core/hle/kernel/thread.h"
11#include "core/memory.h" 12#include "core/memory.h"
12 13
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 90881054c..7b8a68610 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -45,6 +45,8 @@ union ProcessFlags {
45 BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). 45 BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
46}; 46};
47 47
48class ResourceLimit;
49
48class Process final : public Object { 50class Process final : public Object {
49public: 51public:
50 static SharedPtr<Process> Create(std::string name, u64 program_id); 52 static SharedPtr<Process> Create(std::string name, u64 program_id);
@@ -61,6 +63,8 @@ public:
61 std::string name; 63 std::string name;
62 /// Title ID corresponding to the process 64 /// Title ID corresponding to the process
63 u64 program_id; 65 u64 program_id;
66 /// Resource limit descriptor for this process
67 SharedPtr<ResourceLimit> resource_limit;
64 68
65 /// The process may only call SVCs which have the corresponding bit set. 69 /// The process may only call SVCs which have the corresponding bit set.
66 std::bitset<0x80> svc_access_mask; 70 std::bitset<0x80> svc_access_mask;
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp
new file mode 100644
index 000000000..94b3e3298
--- /dev/null
+++ b/src/core/hle/kernel/resource_limit.cpp
@@ -0,0 +1,157 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <cstring>
6
7#include "common/logging/log.h"
8
9#include "core/mem_map.h"
10#include "core/hle/kernel/resource_limit.h"
11
12namespace Kernel {
13
14static SharedPtr<ResourceLimit> resource_limits[4];
15
16ResourceLimit::ResourceLimit() {}
17ResourceLimit::~ResourceLimit() {}
18
19SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) {
20 SharedPtr<ResourceLimit> resource_limit(new ResourceLimit);
21
22 resource_limit->name = std::move(name);
23 return resource_limit;
24}
25
26SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) {
27 switch (category)
28 {
29 case ResourceLimitCategory::APPLICATION:
30 case ResourceLimitCategory::SYS_APPLET:
31 case ResourceLimitCategory::LIB_APPLET:
32 case ResourceLimitCategory::OTHER:
33 return resource_limits[static_cast<u8>(category)];
34 default:
35 LOG_CRITICAL(Kernel, "Unknown resource limit category");
36 UNREACHABLE();
37 }
38}
39
40s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const {
41 switch (resource) {
42 case COMMIT:
43 return current_commit;
44 case THREAD:
45 return current_threads;
46 case EVENT:
47 return current_events;
48 case MUTEX:
49 return current_mutexes;
50 case SEMAPHORE:
51 return current_semaphores;
52 case TIMER:
53 return current_timers;
54 case SHARED_MEMORY:
55 return current_shared_mems;
56 case ADDRESS_ARBITER:
57 return current_address_arbiters;
58 case CPU_TIME:
59 return current_cpu_time;
60 default:
61 LOG_ERROR(Kernel, "Unknown resource type=%08X", resource);
62 UNIMPLEMENTED();
63 return 0;
64 }
65}
66
67s32 ResourceLimit::GetMaxResourceValue(u32 resource) const {
68 switch (resource) {
69 case COMMIT:
70 return max_commit;
71 case THREAD:
72 return max_threads;
73 case EVENT:
74 return max_events;
75 case MUTEX:
76 return max_mutexes;
77 case SEMAPHORE:
78 return max_semaphores;
79 case TIMER:
80 return max_timers;
81 case SHARED_MEMORY:
82 return max_shared_mems;
83 case ADDRESS_ARBITER:
84 return max_address_arbiters;
85 case CPU_TIME:
86 return max_cpu_time;
87 default:
88 LOG_ERROR(Kernel, "Unknown resource type=%08X", resource);
89 UNIMPLEMENTED();
90 return 0;
91 }
92}
93
94void ResourceLimitsInit() {
95 // Create the four resource limits that the system uses
96 // Create the APPLICATION resource limit
97 SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create("Applications");
98 resource_limit->max_priority = 0x18;
99 resource_limit->max_commit = 0x4000000;
100 resource_limit->max_threads = 0x20;
101 resource_limit->max_events = 0x20;
102 resource_limit->max_mutexes = 0x20;
103 resource_limit->max_semaphores = 0x8;
104 resource_limit->max_timers = 0x8;
105 resource_limit->max_shared_mems = 0x10;
106 resource_limit->max_address_arbiters = 0x2;
107 resource_limit->max_cpu_time = 0x1E;
108 resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit;
109
110 // Create the SYS_APPLET resource limit
111 resource_limit = ResourceLimit::Create("System Applets");
112 resource_limit->max_priority = 0x4;
113 resource_limit->max_commit = 0x5E00000;
114 resource_limit->max_threads = 0x1D;
115 resource_limit->max_events = 0xB;
116 resource_limit->max_mutexes = 0x8;
117 resource_limit->max_semaphores = 0x4;
118 resource_limit->max_timers = 0x4;
119 resource_limit->max_shared_mems = 0x8;
120 resource_limit->max_address_arbiters = 0x3;
121 resource_limit->max_cpu_time = 0x2710;
122 resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit;
123
124 // Create the LIB_APPLET resource limit
125 resource_limit = ResourceLimit::Create("Library Applets");
126 resource_limit->max_priority = 0x4;
127 resource_limit->max_commit = 0x600000;
128 resource_limit->max_threads = 0xE;
129 resource_limit->max_events = 0x8;
130 resource_limit->max_mutexes = 0x8;
131 resource_limit->max_semaphores = 0x4;
132 resource_limit->max_timers = 0x4;
133 resource_limit->max_shared_mems = 0x8;
134 resource_limit->max_address_arbiters = 0x1;
135 resource_limit->max_cpu_time = 0x2710;
136 resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit;
137
138 // Create the OTHER resource limit
139 resource_limit = ResourceLimit::Create("Others");
140 resource_limit->max_priority = 0x4;
141 resource_limit->max_commit = 0x2180000;
142 resource_limit->max_threads = 0xE1;
143 resource_limit->max_events = 0x108;
144 resource_limit->max_mutexes = 0x25;
145 resource_limit->max_semaphores = 0x43;
146 resource_limit->max_timers = 0x2C;
147 resource_limit->max_shared_mems = 0x1F;
148 resource_limit->max_address_arbiters = 0x2D;
149 resource_limit->max_cpu_time = 0x3E8;
150 resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit;
151}
152
153void ResourceLimitsShutdown() {
154
155}
156
157} // namespace
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
new file mode 100644
index 000000000..201ec0db9
--- /dev/null
+++ b/src/core/hle/kernel/resource_limit.h
@@ -0,0 +1,119 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9#include "core/hle/kernel/kernel.h"
10
11namespace Kernel {
12
13enum class ResourceLimitCategory : u8 {
14 APPLICATION = 0,
15 SYS_APPLET = 1,
16 LIB_APPLET = 2,
17 OTHER = 3
18};
19
20enum ResourceTypes {
21 PRIORITY = 0,
22 COMMIT = 1,
23 THREAD = 2,
24 EVENT = 3,
25 MUTEX = 4,
26 SEMAPHORE = 5,
27 TIMER = 6,
28 SHARED_MEMORY = 7,
29 ADDRESS_ARBITER = 8,
30 CPU_TIME = 9,
31};
32
33class ResourceLimit final : public Object {
34public:
35 /**
36 * Creates a resource limit object.
37 */
38 static SharedPtr<ResourceLimit> Create(std::string name = "Unknown");
39
40 /**
41 * Retrieves the resource limit associated with the specified resource limit category.
42 * @param category The resource limit category
43 * @returns The resource limit associated with the category
44 */
45 static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category);
46
47 std::string GetTypeName() const override { return "ResourceLimit"; }
48 std::string GetName() const override { return name; }
49
50 static const HandleType HANDLE_TYPE = HandleType::ResourceLimit;
51 HandleType GetHandleType() const override { return HANDLE_TYPE; }
52
53 /**
54 * Gets the current value for the specified resource.
55 * @param resource Requested resource type
56 * @returns The current value of the resource type
57 */
58 s32 GetCurrentResourceValue(u32 resource) const;
59
60 /**
61 * Gets the max value for the specified resource.
62 * @param resource Requested resource type
63 * @returns The max value of the resource type
64 */
65 s32 GetMaxResourceValue(u32 resource) const;
66
67 /// Name of resource limit object.
68 std::string name;
69
70 /// Max thread priority that a process in this category can create
71 s32 max_priority = 0;
72
73 /// Max memory that processes in this category can use
74 s32 max_commit = 0;
75
76 ///< Max number of objects that can be collectively created by the processes in this category
77 s32 max_threads = 0;
78 s32 max_events = 0;
79 s32 max_mutexes = 0;
80 s32 max_semaphores = 0;
81 s32 max_timers = 0;
82 s32 max_shared_mems = 0;
83 s32 max_address_arbiters = 0;
84
85 /// Max CPU time that the processes in this category can utilize
86 s32 max_cpu_time = 0;
87
88 // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind that
89 // APPLICATION resource limits should not be affected by the objects created by service modules.
90 // Currently we have no way of distinguishing if a Create was called by the running application,
91 // or by a service module. Approach this once we have separated the service modules into their own processes
92
93 /// Current memory that the processes in this category are using
94 s32 current_commit = 0;
95
96 ///< Current number of objects among all processes in this category
97 s32 current_threads = 0;
98 s32 current_events = 0;
99 s32 current_mutexes = 0;
100 s32 current_semaphores = 0;
101 s32 current_timers = 0;
102 s32 current_shared_mems = 0;
103 s32 current_address_arbiters = 0;
104
105 /// Current CPU time that the processes in this category are utilizing
106 s32 current_cpu_time = 0;
107
108private:
109 ResourceLimit();
110 ~ResourceLimit() override;
111};
112
113/// Initializes the resource limits
114void ResourceLimitsInit();
115
116// Destroys the resource limits
117void ResourceLimitsShutdown();
118
119} // namespace