aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/config_mem.cpp49
-rw-r--r--src/core/hle/config_mem.h38
-rw-r--r--src/core/hle/coprocessor.cpp33
-rw-r--r--src/core/hle/function_wrappers.h14
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp2
-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.cpp9
-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
-rw-r--r--src/core/hle/kernel/session.h2
-rw-r--r--src/core/hle/kernel/shared_memory.cpp2
-rw-r--r--src/core/hle/kernel/thread.cpp4
-rw-r--r--src/core/hle/kernel/thread.h1
-rw-r--r--src/core/hle/service/apt/apt.cpp2
-rw-r--r--src/core/hle/service/fs/fs_user.cpp8
-rw-r--r--src/core/hle/service/gsp_gpu.cpp1
-rw-r--r--src/core/hle/shared_page.cpp57
-rw-r--r--src/core/hle/shared_page.h38
-rw-r--r--src/core/hle/svc.cpp63
21 files changed, 434 insertions, 175 deletions
diff --git a/src/core/hle/config_mem.cpp b/src/core/hle/config_mem.cpp
index 35dc9cf5..aea936d2 100644
--- a/src/core/hle/config_mem.cpp
+++ b/src/core/hle/config_mem.cpp
@@ -9,59 +9,14 @@
#include "common/common_funcs.h"
#include "core/core.h"
-#include "core/mem_map.h"
+#include "core/memory.h"
#include "core/hle/config_mem.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace ConfigMem {
-struct ConfigMemDef {
- u8 kernel_unk; // 0
- u8 kernel_version_rev; // 1
- u8 kernel_version_min; // 2
- u8 kernel_version_maj; // 3
- u32 update_flag; // 4
- u64 ns_tid; // 8
- u32 sys_core_ver; // 10
- u8 unit_info; // 14
- u8 boot_firm; // 15
- u8 prev_firm; // 16
- INSERT_PADDING_BYTES(0x1); // 17
- u32 ctr_sdk_ver; // 18
- INSERT_PADDING_BYTES(0x30 - 0x1C); // 1C
- u32 app_mem_type; // 30
- INSERT_PADDING_BYTES(0x40 - 0x34); // 34
- u32 app_mem_alloc; // 40
- u32 sys_mem_alloc; // 44
- u32 base_mem_alloc; // 48
- INSERT_PADDING_BYTES(0x60 - 0x4C); // 4C
- u8 firm_unk; // 60
- u8 firm_version_rev; // 61
- u8 firm_version_min; // 62
- u8 firm_version_maj; // 63
- u32 firm_sys_core_ver; // 64
- u32 firm_ctr_sdk_ver; // 68
- INSERT_PADDING_BYTES(0x1000 - 0x6C); // 6C
-};
-
-static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, "Config Memory structure size is wrong");
-
-static ConfigMemDef config_mem;
-
-template <typename T>
-inline void Read(T &var, const u32 addr) {
- u32 offset = addr - Memory::CONFIG_MEMORY_VADDR;
- ASSERT(offset < Memory::CONFIG_MEMORY_SIZE);
- var = *(reinterpret_cast<T*>(((uintptr_t)&config_mem) + offset));
-}
-
-// Explicitly instantiate template functions because we aren't defining this in the header:
-
-template void Read<u64>(u64 &var, const u32 addr);
-template void Read<u32>(u32 &var, const u32 addr);
-template void Read<u16>(u16 &var, const u32 addr);
-template void Read<u8>(u8 &var, const u32 addr);
+ConfigMemDef config_mem;
void Init() {
std::memset(&config_mem, 0, sizeof(config_mem));
diff --git a/src/core/hle/config_mem.h b/src/core/hle/config_mem.h
index cbb478fb..9825a09e 100644
--- a/src/core/hle/config_mem.h
+++ b/src/core/hle/config_mem.h
@@ -9,17 +9,49 @@
// bootrom. Because we're not emulating this, and essentially just "stubbing" the functionality, I'm
// putting this as a subset of HLE for now.
+#include "common/common_funcs.h"
#include "common/common_types.h"
+#include "common/swap.h"
+
+#include "core/memory.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace ConfigMem {
-template <typename T>
-void Read(T &var, const u32 addr);
+struct ConfigMemDef {
+ u8 kernel_unk; // 0
+ u8 kernel_version_rev; // 1
+ u8 kernel_version_min; // 2
+ u8 kernel_version_maj; // 3
+ u32_le update_flag; // 4
+ u64_le ns_tid; // 8
+ u32_le sys_core_ver; // 10
+ u8 unit_info; // 14
+ u8 boot_firm; // 15
+ u8 prev_firm; // 16
+ INSERT_PADDING_BYTES(0x1); // 17
+ u32_le ctr_sdk_ver; // 18
+ INSERT_PADDING_BYTES(0x30 - 0x1C); // 1C
+ u32_le app_mem_type; // 30
+ INSERT_PADDING_BYTES(0x40 - 0x34); // 34
+ u32_le app_mem_alloc; // 40
+ u32_le sys_mem_alloc; // 44
+ u32_le base_mem_alloc; // 48
+ INSERT_PADDING_BYTES(0x60 - 0x4C); // 4C
+ u8 firm_unk; // 60
+ u8 firm_version_rev; // 61
+ u8 firm_version_min; // 62
+ u8 firm_version_maj; // 63
+ u32_le firm_sys_core_ver; // 64
+ u32_le firm_ctr_sdk_ver; // 68
+ INSERT_PADDING_BYTES(0x1000 - 0x6C); // 6C
+};
+static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, "Config Memory structure size is wrong");
+
+extern ConfigMemDef config_mem;
void Init();
-
void Shutdown();
} // namespace
diff --git a/src/core/hle/coprocessor.cpp b/src/core/hle/coprocessor.cpp
deleted file mode 100644
index 425959be..00000000
--- a/src/core/hle/coprocessor.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "core/hle/coprocessor.h"
-#include "core/hle/hle.h"
-#include "core/mem_map.h"
-
-namespace HLE {
-
-/// Returns the coprocessor (in this case, syscore) command buffer pointer
-Addr GetThreadCommandBuffer() {
- // Called on insruction: mrc p15, 0, r0, c13, c0, 3
- return Memory::KERNEL_MEMORY_VADDR;
-}
-
-/// Call an MRC (move to ARM register from coprocessor) instruction in HLE
-s32 CallMRC(u32 instruction) {
- CoprocessorOperation operation = (CoprocessorOperation)((instruction >> 20) & 0xFF);
-
- switch (operation) {
-
- case CALL_GET_THREAD_COMMAND_BUFFER:
- return GetThreadCommandBuffer();
-
- default:
- DEBUG_LOG(OSHLE, "unknown MRC call 0x%08X", instruction);
- break;
- }
- return -1;
-}
-
-} // namespace
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index be2626ee..23c86a72 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -7,7 +7,7 @@
#include "common/common_types.h"
#include "core/arm/arm_interface.h"
-#include "core/mem_map.h"
+#include "core/memory.h"
#include "core/hle/hle.h"
namespace HLE {
@@ -102,14 +102,14 @@ template<ResultCode func(u32)> void Wrap() {
FuncReturn(func(PARAM(0)).raw);
}
-template<ResultCode func(s64*, u32, void*, s32)> void Wrap(){
- FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), Memory::GetPointer(PARAM(2)),
+template<ResultCode func(s64*, u32, u32*, s32)> void Wrap(){
+ FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), (u32*)Memory::GetPointer(PARAM(2)),
(s32)PARAM(3)).raw);
}
template<ResultCode func(u32*, const char*)> void Wrap() {
u32 param_1 = 0;
- u32 retval = func(&param_1, Memory::GetCharPointer(PARAM(1))).raw;
+ u32 retval = func(&param_1, (char*)Memory::GetPointer(PARAM(1))).raw;
Core::g_app_core->SetReg(1, param_1);
FuncReturn(retval);
}
@@ -163,7 +163,11 @@ template<void func(s64)> void Wrap() {
}
template<void func(const char*)> void Wrap() {
- func(Memory::GetCharPointer(PARAM(0)));
+ func((char*)Memory::GetPointer(PARAM(0)));
+}
+
+template<void func(u8)> void Wrap() {
+ func((u8)PARAM(0));
}
#undef PARAM
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 9d7f6b28..a1221766 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -5,7 +5,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
-#include "core/mem_map.h"
+#include "core/memory.h"
#include "core/hle/hle.h"
#include "core/hle/kernel/address_arbiter.h"
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index b5c98b24..726e4d2f 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -10,6 +10,7 @@
#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
@@ -134,6 +135,7 @@ void HandleTable::Clear() {
/// Initialize the kernel
void Init() {
+ Kernel::ResourceLimitsInit();
Kernel::ThreadingInit();
Kernel::TimersInit();
@@ -147,6 +149,7 @@ void Init() {
void Shutdown() {
Kernel::ThreadingShutdown();
Kernel::TimersShutdown();
+ Kernel::ResourceLimitsShutdown();
g_handle_table.Clear(); // Free all kernel objects
g_current_process = nullptr;
}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 7c106d37..28748c8f 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -46,7 +46,8 @@ enum class HandleType : u32 {
Process = 8,
AddressArbiter = 9,
Semaphore = 10,
- Timer = 11
+ Timer = 11,
+ ResourceLimit = 12,
};
enum {
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 1e439db9..b0e75ba5 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -7,8 +7,9 @@
#include "common/logging/log.h"
#include "core/hle/kernel/process.h"
+#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/thread.h"
-#include "core/mem_map.h"
+#include "core/memory.h"
namespace Kernel {
@@ -27,7 +28,7 @@ SharedPtr<Process> Process::Create(std::string name, u64 program_id) {
}
void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
- for (int i = 0; i < len; ++i) {
+ for (size_t i = 0; i < len; ++i) {
u32 descriptor = kernel_caps[i];
u32 type = descriptor >> 20;
@@ -64,8 +65,8 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
AddressMapping mapping;
mapping.address = descriptor << 12;
mapping.size = (end_desc << 12) - mapping.address;
- mapping.writable = descriptor & (1 << 20);
- mapping.unk_flag = end_desc & (1 << 20);
+ mapping.writable = (descriptor & (1 << 20)) != 0;
+ mapping.unk_flag = (end_desc & (1 << 20)) != 0;
address_mappings.push_back(mapping);
} else if ((type & 0xFFF) == 0xFFE) { // 0x000F
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 90881054..7b8a6861 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -45,6 +45,8 @@ union ProcessFlags {
BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
};
+class ResourceLimit;
+
class Process final : public Object {
public:
static SharedPtr<Process> Create(std::string name, u64 program_id);
@@ -61,6 +63,8 @@ public:
std::string name;
/// Title ID corresponding to the process
u64 program_id;
+ /// Resource limit descriptor for this process
+ SharedPtr<ResourceLimit> resource_limit;
/// The process may only call SVCs which have the corresponding bit set.
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 00000000..94b3e329
--- /dev/null
+++ b/src/core/hle/kernel/resource_limit.cpp
@@ -0,0 +1,157 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <cstring>
+
+#include "common/logging/log.h"
+
+#include "core/mem_map.h"
+#include "core/hle/kernel/resource_limit.h"
+
+namespace Kernel {
+
+static SharedPtr<ResourceLimit> resource_limits[4];
+
+ResourceLimit::ResourceLimit() {}
+ResourceLimit::~ResourceLimit() {}
+
+SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) {
+ SharedPtr<ResourceLimit> resource_limit(new ResourceLimit);
+
+ resource_limit->name = std::move(name);
+ return resource_limit;
+}
+
+SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) {
+ switch (category)
+ {
+ case ResourceLimitCategory::APPLICATION:
+ case ResourceLimitCategory::SYS_APPLET:
+ case ResourceLimitCategory::LIB_APPLET:
+ case ResourceLimitCategory::OTHER:
+ return resource_limits[static_cast<u8>(category)];
+ default:
+ LOG_CRITICAL(Kernel, "Unknown resource limit category");
+ UNREACHABLE();
+ }
+}
+
+s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const {
+ switch (resource) {
+ case COMMIT:
+ return current_commit;
+ case THREAD:
+ return current_threads;
+ case EVENT:
+ return current_events;
+ case MUTEX:
+ return current_mutexes;
+ case SEMAPHORE:
+ return current_semaphores;
+ case TIMER:
+ return current_timers;
+ case SHARED_MEMORY:
+ return current_shared_mems;
+ case ADDRESS_ARBITER:
+ return current_address_arbiters;
+ case CPU_TIME:
+ return current_cpu_time;
+ default:
+ LOG_ERROR(Kernel, "Unknown resource type=%08X", resource);
+ UNIMPLEMENTED();
+ return 0;
+ }
+}
+
+s32 ResourceLimit::GetMaxResourceValue(u32 resource) const {
+ switch (resource) {
+ case COMMIT:
+ return max_commit;
+ case THREAD:
+ return max_threads;
+ case EVENT:
+ return max_events;
+ case MUTEX:
+ return max_mutexes;
+ case SEMAPHORE:
+ return max_semaphores;
+ case TIMER:
+ return max_timers;
+ case SHARED_MEMORY:
+ return max_shared_mems;
+ case ADDRESS_ARBITER:
+ return max_address_arbiters;
+ case CPU_TIME:
+ return max_cpu_time;
+ default:
+ LOG_ERROR(Kernel, "Unknown resource type=%08X", resource);
+ UNIMPLEMENTED();
+ return 0;
+ }
+}
+
+void ResourceLimitsInit() {
+ // Create the four resource limits that the system uses
+ // Create the APPLICATION resource limit
+ SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create("Applications");
+ resource_limit->max_priority = 0x18;
+ resource_limit->max_commit = 0x4000000;
+ resource_limit->max_threads = 0x20;
+ resource_limit->max_events = 0x20;
+ resource_limit->max_mutexes = 0x20;
+ resource_limit->max_semaphores = 0x8;
+ resource_limit->max_timers = 0x8;
+ resource_limit->max_shared_mems = 0x10;
+ resource_limit->max_address_arbiters = 0x2;
+ resource_limit->max_cpu_time = 0x1E;
+ resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit;
+
+ // Create the SYS_APPLET resource limit
+ resource_limit = ResourceLimit::Create("System Applets");
+ resource_limit->max_priority = 0x4;
+ resource_limit->max_commit = 0x5E00000;
+ resource_limit->max_threads = 0x1D;
+ resource_limit->max_events = 0xB;
+ resource_limit->max_mutexes = 0x8;
+ resource_limit->max_semaphores = 0x4;
+ resource_limit->max_timers = 0x4;
+ resource_limit->max_shared_mems = 0x8;
+ resource_limit->max_address_arbiters = 0x3;
+ resource_limit->max_cpu_time = 0x2710;
+ resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit;
+
+ // Create the LIB_APPLET resource limit
+ resource_limit = ResourceLimit::Create("Library Applets");
+ resource_limit->max_priority = 0x4;
+ resource_limit->max_commit = 0x600000;
+ resource_limit->max_threads = 0xE;
+ resource_limit->max_events = 0x8;
+ resource_limit->max_mutexes = 0x8;
+ resource_limit->max_semaphores = 0x4;
+ resource_limit->max_timers = 0x4;
+ resource_limit->max_shared_mems = 0x8;
+ resource_limit->max_address_arbiters = 0x1;
+ resource_limit->max_cpu_time = 0x2710;
+ resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit;
+
+ // Create the OTHER resource limit
+ resource_limit = ResourceLimit::Create("Others");
+ resource_limit->max_priority = 0x4;
+ resource_limit->max_commit = 0x2180000;
+ resource_limit->max_threads = 0xE1;
+ resource_limit->max_events = 0x108;
+ resource_limit->max_mutexes = 0x25;
+ resource_limit->max_semaphores = 0x43;
+ resource_limit->max_timers = 0x2C;
+ resource_limit->max_shared_mems = 0x1F;
+ resource_limit->max_address_arbiters = 0x2D;
+ resource_limit->max_cpu_time = 0x3E8;
+ resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit;
+}
+
+void ResourceLimitsShutdown() {
+
+}
+
+} // namespace
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
new file mode 100644
index 00000000..201ec0db
--- /dev/null
+++ b/src/core/hle/kernel/resource_limit.h
@@ -0,0 +1,119 @@
+// Copyright 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "common/common_types.h"
+
+#include "core/hle/kernel/kernel.h"
+
+namespace Kernel {
+
+enum class ResourceLimitCategory : u8 {
+ APPLICATION = 0,
+ SYS_APPLET = 1,
+ LIB_APPLET = 2,
+ OTHER = 3
+};
+
+enum ResourceTypes {
+ PRIORITY = 0,
+ COMMIT = 1,
+ THREAD = 2,
+ EVENT = 3,
+ MUTEX = 4,
+ SEMAPHORE = 5,
+ TIMER = 6,
+ SHARED_MEMORY = 7,
+ ADDRESS_ARBITER = 8,
+ CPU_TIME = 9,
+};
+
+class ResourceLimit final : public Object {
+public:
+ /**
+ * Creates a resource limit object.
+ */
+ static SharedPtr<ResourceLimit> Create(std::string name = "Unknown");
+
+ /**
+ * Retrieves the resource limit associated with the specified resource limit category.
+ * @param category The resource limit category
+ * @returns The resource limit associated with the category
+ */
+ static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category);
+
+ std::string GetTypeName() const override { return "ResourceLimit"; }
+ std::string GetName() const override { return name; }
+
+ static const HandleType HANDLE_TYPE = HandleType::ResourceLimit;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
+
+ /**
+ * Gets the current value for the specified resource.
+ * @param resource Requested resource type
+ * @returns The current value of the resource type
+ */
+ s32 GetCurrentResourceValue(u32 resource) const;
+
+ /**
+ * Gets the max value for the specified resource.
+ * @param resource Requested resource type
+ * @returns The max value of the resource type
+ */
+ s32 GetMaxResourceValue(u32 resource) const;
+
+ /// Name of resource limit object.
+ std::string name;
+
+ /// Max thread priority that a process in this category can create
+ s32 max_priority = 0;
+
+ /// Max memory that processes in this category can use
+ s32 max_commit = 0;
+
+ ///< Max number of objects that can be collectively created by the processes in this category
+ s32 max_threads = 0;
+ s32 max_events = 0;
+ s32 max_mutexes = 0;
+ s32 max_semaphores = 0;
+ s32 max_timers = 0;
+ s32 max_shared_mems = 0;
+ s32 max_address_arbiters = 0;
+
+ /// Max CPU time that the processes in this category can utilize
+ s32 max_cpu_time = 0;
+
+ // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind that
+ // APPLICATION resource limits should not be affected by the objects created by service modules.
+ // Currently we have no way of distinguishing if a Create was called by the running application,
+ // or by a service module. Approach this once we have separated the service modules into their own processes
+
+ /// Current memory that the processes in this category are using
+ s32 current_commit = 0;
+
+ ///< Current number of objects among all processes in this category
+ s32 current_threads = 0;
+ s32 current_events = 0;
+ s32 current_mutexes = 0;
+ s32 current_semaphores = 0;
+ s32 current_timers = 0;
+ s32 current_shared_mems = 0;
+ s32 current_address_arbiters = 0;
+
+ /// Current CPU time that the processes in this category are utilizing
+ s32 current_cpu_time = 0;
+
+private:
+ ResourceLimit();
+ ~ResourceLimit() override;
+};
+
+/// Initializes the resource limits
+void ResourceLimitsInit();
+
+// Destroys the resource limits
+void ResourceLimitsShutdown();
+
+} // namespace
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index 8c3886ff..54a06297 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -6,7 +6,7 @@
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/thread.h"
-#include "core/mem_map.h"
+#include "core/memory.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index 0c59f487..4137683b 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -6,7 +6,7 @@
#include "common/logging/log.h"
-#include "core/mem_map.h"
+#include "core/memory.h"
#include "core/hle/kernel/shared_memory.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index afaf0cd5..a5f1904d 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -21,7 +21,7 @@
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/mutex.h"
#include "core/hle/result.h"
-#include "core/mem_map.h"
+#include "core/memory.h"
namespace Kernel {
@@ -495,7 +495,7 @@ void Reschedule() {
LOG_TRACE(Kernel, "context switch %u -> %u", cur->GetObjectId(), next->GetObjectId());
} else if (cur) {
LOG_TRACE(Kernel, "context switch %u -> idle", cur->GetObjectId());
- } else {
+ } else if (next) {
LOG_TRACE(Kernel, "context switch idle -> %u", next->GetObjectId());
}
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 6b329c12..38992817 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -12,7 +12,6 @@
#include "common/common_types.h"
#include "core/core.h"
-#include "core/mem_map.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/result.h"
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 09d463dd..3fd4cfb0 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -269,8 +269,6 @@ void GetAppCpuTimeLimit(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 value = cmd_buff[1];
- ASSERT(cpu_percent != 0);
-
if (value != 1) {
LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value);
}
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index 0d2a426b..b25c8941 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -650,7 +650,7 @@ static void SetPriority(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw;
- LOG_DEBUG(Service_FS, "called priority=0x%08X", priority);
+ LOG_DEBUG(Service_FS, "called priority=0x%X", priority);
}
/**
@@ -664,12 +664,14 @@ static void SetPriority(Service::Interface* self) {
static void GetPriority(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- ASSERT(priority != -1);
+ if (priority == -1) {
+ LOG_INFO(Service_FS, "priority was not set, priority=0x%X", priority);
+ }
cmd_buff[1] = RESULT_SUCCESS.raw;
cmd_buff[2] = priority;
- LOG_DEBUG(Service_FS, "called priority=0x%08X", priority);
+ LOG_DEBUG(Service_FS, "called priority=0x%X", priority);
}
const Interface::FunctionInfo FunctionTable[] = {
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index c6252a03..c11c5fab 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -5,6 +5,7 @@
#include "common/bit_field.h"
#include "core/mem_map.h"
+#include "core/memory.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/result.h"
diff --git a/src/core/hle/shared_page.cpp b/src/core/hle/shared_page.cpp
index 4f227a37..4014eee9 100644
--- a/src/core/hle/shared_page.cpp
+++ b/src/core/hle/shared_page.cpp
@@ -8,7 +8,7 @@
#include "common/common_funcs.h"
#include "core/core.h"
-#include "core/mem_map.h"
+#include "core/memory.h"
#include "core/hle/config_mem.h"
#include "core/hle/shared_page.h"
@@ -16,63 +16,12 @@
namespace SharedPage {
-// see http://3dbrew.org/wiki/Configuration_Memory#Shared_Memory_Page_For_ARM11_Processes
+SharedPageDef shared_page;
-#pragma pack(1)
-struct DateTime {
- u64 date_time; // 0x0
- u64 update_tick; // 0x8
- INSERT_PADDING_BYTES(0x20 - 0x10); // 0x10
-};
-
-struct SharedPageDef {
- // most of these names are taken from the 3dbrew page linked above.
- u32 date_time_selector; // 0x0
- u8 running_hw; // 0x4
- u8 mcu_hw_info; // 0x5: don't know what the acronyms mean
- INSERT_PADDING_BYTES(0x20 - 0x6); // 0x6
- DateTime date_time_0; // 0x20
- DateTime date_time_1; // 0x40
- u8 wifi_macaddr[6]; // 0x60
- u8 wifi_unknown1; // 0x66: 3dbrew says these are "Likely wifi hardware related"
- u8 wifi_unknown2; // 0x67
- INSERT_PADDING_BYTES(0x80 - 0x68); // 0x68
- float sliderstate_3d; // 0x80
- u8 ledstate_3d; // 0x84
- INSERT_PADDING_BYTES(0xA0 - 0x85); // 0x85
- u64 menu_title_id; // 0xA0
- u64 active_menu_title_id; // 0xA8
- INSERT_PADDING_BYTES(0x1000 - 0xB0); // 0xB0
-};
-#pragma pack()
-
-static_assert(sizeof(DateTime) == 0x20, "Datetime size is wrong");
-static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, "Shared page structure size is wrong");
-
-static SharedPageDef shared_page;
-
-template <typename T>
-inline void Read(T &var, const u32 addr) {
- u32 offset = addr - Memory::SHARED_PAGE_VADDR;
- var = *(reinterpret_cast<T*>(((uintptr_t)&shared_page) + offset));
-}
-
-// Explicitly instantiate template functions because we aren't defining this in the header:
-template void Read<u64>(u64 &var, const u32 addr);
-template void Read<u32>(u32 &var, const u32 addr);
-template void Read<u16>(u16 &var, const u32 addr);
-template void Read<u8>(u8 &var, const u32 addr);
-
-void Set3DSlider(float amount) {
+void Init() {
std::memset(&shared_page, 0, sizeof(shared_page));
- shared_page.sliderstate_3d = amount;
- shared_page.ledstate_3d = (amount == 0.0f); // off when non-zero
-}
-
-void Init() {
shared_page.running_hw = 0x1; // product
- Set3DSlider(0.0f);
}
void Shutdown() {
diff --git a/src/core/hle/shared_page.h b/src/core/hle/shared_page.h
index 1b6e4e58..fd2ab66a 100644
--- a/src/core/hle/shared_page.h
+++ b/src/core/hle/shared_page.h
@@ -11,18 +11,46 @@
*/
#include "common/common_types.h"
+#include "common/swap.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace SharedPage {
-template <typename T>
-void Read(T &var, const u32 addr);
-
-void Set3DSlider(float amount);
+// See http://3dbrew.org/wiki/Configuration_Memory#Shared_Memory_Page_For_ARM11_Processes
+
+struct DateTime {
+ u64_le date_time; // 0
+ u64_le update_tick; // 8
+ INSERT_PADDING_BYTES(0x20 - 0x10); // 10
+};
+static_assert(sizeof(DateTime) == 0x20, "Datetime size is wrong");
+
+struct SharedPageDef {
+ // Most of these names are taken from the 3dbrew page linked above.
+ u32_le date_time_selector; // 0
+ u8 running_hw; // 4
+ /// "Microcontroller hardware info"
+ u8 mcu_hw_info; // 5
+ INSERT_PADDING_BYTES(0x20 - 0x6); // 6
+ DateTime date_time_0; // 20
+ DateTime date_time_1; // 40
+ u8 wifi_macaddr[6]; // 60
+ u8 wifi_unknown1; // 66
+ u8 wifi_unknown2; // 67
+ INSERT_PADDING_BYTES(0x80 - 0x68); // 68
+ float_le sliderstate_3d; // 80
+ u8 ledstate_3d; // 84
+ INSERT_PADDING_BYTES(0xA0 - 0x85); // 85
+ u64_le menu_title_id; // A0
+ u64_le active_menu_title_id; // A8
+ INSERT_PADDING_BYTES(0x1000 - 0xB0); // B0
+};
+static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, "Shared page structure size is wrong");
+
+extern SharedPageDef shared_page;
void Init();
-
void Shutdown();
} // namespace
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index e8159fbd..22adf959 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -17,6 +17,7 @@
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/mutex.h"
#include "core/hle/kernel/process.h"
+#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/semaphore.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/kernel/thread.h"
@@ -295,27 +296,65 @@ static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 val
return res;
}
+static void Break(u8 break_reason) {
+ LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!");
+ std::string reason_str;
+ switch (break_reason) {
+ case 0: reason_str = "PANIC"; break;
+ case 1: reason_str = "ASSERT"; break;
+ case 2: reason_str = "USER"; break;
+ default: reason_str = "UNKNOWN"; break;
+ }
+ LOG_CRITICAL(Debug_Emulated, "Break reason: %s", reason_str.c_str());
+}
+
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
static void OutputDebugString(const char* string) {
LOG_DEBUG(Debug_Emulated, "%s", string);
}
/// Get resource limit
-static ResultCode GetResourceLimit(Handle* resource_limit, Handle process) {
- // With regards to proceess values:
- // 0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for
- // the current KThread.
- *resource_limit = 0xDEADBEEF;
- LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called process=0x%08X", process);
+static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) {
+ LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle);
+
+ SharedPtr<Kernel::Process> process = Kernel::g_handle_table.Get<Kernel::Process>(process_handle);
+ if (process == nullptr)
+ return ERR_INVALID_HANDLE;
+
+ CASCADE_RESULT(*resource_limit, Kernel::g_handle_table.Create(process->resource_limit));
+
return RESULT_SUCCESS;
}
/// Get resource limit current values
-static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit, void* names,
+static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, u32* names,
s32 name_count) {
- LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called resource_limit=%08X, names=%p, name_count=%d",
- resource_limit, names, name_count);
- Memory::Write32(Core::g_app_core->GetReg(0), 0); // Normmatt: Set used memory to 0 for now
+ LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
+ resource_limit_handle, names, name_count);
+
+ SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle);
+ if (resource_limit == nullptr)
+ return ERR_INVALID_HANDLE;
+
+ for (unsigned int i = 0; i < name_count; ++i)
+ values[i] = resource_limit->GetCurrentResourceValue(names[i]);
+
+ return RESULT_SUCCESS;
+}
+
+/// Get resource limit max values
+static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names,
+ s32 name_count) {
+ LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
+ resource_limit_handle, names, name_count);
+
+ SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle);
+ if (resource_limit == nullptr)
+ return ERR_INVALID_HANDLE;
+
+ for (unsigned int i = 0; i < name_count; ++i)
+ values[i] = resource_limit->GetMaxResourceValue(names[i]);
+
return RESULT_SUCCESS;
}
@@ -707,10 +746,10 @@ static const FunctionDef SVC_Table[] = {
{0x36, HLE::Wrap<GetProcessIdOfThread>, "GetProcessIdOfThread"},
{0x37, HLE::Wrap<GetThreadId>, "GetThreadId"},
{0x38, HLE::Wrap<GetResourceLimit>, "GetResourceLimit"},
- {0x39, nullptr, "GetResourceLimitLimitValues"},
+ {0x39, HLE::Wrap<GetResourceLimitLimitValues>, "GetResourceLimitLimitValues"},
{0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"},
{0x3B, nullptr, "GetThreadContext"},
- {0x3C, nullptr, "Break"},
+ {0x3C, HLE::Wrap<Break>, "Break"},
{0x3D, HLE::Wrap<OutputDebugString>, "OutputDebugString"},
{0x3E, nullptr, "ControlPerformanceCounter"},
{0x3F, nullptr, "Unknown"},