summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/function_wrappers.h8
-rw-r--r--src/core/hle/kernel/memory.cpp2
-rw-r--r--src/core/hle/kernel/memory.h1
-rw-r--r--src/core/hle/kernel/process.cpp6
-rw-r--r--src/core/hle/kernel/thread.cpp3
-rw-r--r--src/core/hle/service/csnd_snd.cpp25
-rw-r--r--src/core/hle/service/ssl_c.cpp53
-rw-r--r--src/core/hle/svc.cpp47
-rw-r--r--src/core/hle/svc.h29
9 files changed, 159 insertions, 15 deletions
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 5846a161b..3501e45db 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -159,6 +159,14 @@ template<ResultCode func(s32*, u32, s32)> void Wrap() {
FuncReturn(retval);
}
+template<ResultCode func(s64*, u32, s32)> void Wrap() {
+ s64 param_1 = 0;
+ u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw;
+ Core::g_app_core->SetReg(1, (u32)param_1);
+ Core::g_app_core->SetReg(2, (u32)(param_1 >> 32));
+ FuncReturn(retval);
+}
+
template<ResultCode func(u32*, u32, u32, u32, u32)> void Wrap() {
u32 param_1 = 0;
u32 retval = func(&param_1, PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw;
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp
index e4fc5f3c4..0cfb43fc7 100644
--- a/src/core/hle/kernel/memory.cpp
+++ b/src/core/hle/kernel/memory.cpp
@@ -51,6 +51,7 @@ void MemoryInit(u32 mem_type) {
for (int i = 0; i < 3; ++i) {
memory_regions[i].base = base;
memory_regions[i].size = memory_region_sizes[mem_type][i];
+ memory_regions[i].used = 0;
memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>();
base += memory_regions[i].size;
@@ -72,6 +73,7 @@ void MemoryShutdown() {
for (auto& region : memory_regions) {
region.base = 0;
region.size = 0;
+ region.used = 0;
region.linear_heap_memory = nullptr;
}
}
diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h
index 36690b091..091c1f89f 100644
--- a/src/core/hle/kernel/memory.h
+++ b/src/core/hle/kernel/memory.h
@@ -17,6 +17,7 @@ class VMManager;
struct MemoryRegionInfo {
u32 base; // Not an address, but offset from start of FCRAM
u32 size;
+ u32 used;
std::shared_ptr<std::vector<u8>> linear_heap_memory;
};
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index c2b4963d4..d148efde2 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -111,6 +111,7 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) {
segment.offset, segment.size, memory_state).Unwrap();
vm_manager.Reprotect(vma, permissions);
misc_memory_used += segment.size;
+ memory_region->used += segment.size;
};
// Map CodeSet segments
@@ -123,6 +124,7 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) {
std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, MemoryState::Locked
).Unwrap();
misc_memory_used += stack_size;
+ memory_region->used += stack_size;
vm_manager.LogLayout(Log::Level::Debug);
Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority);
@@ -165,6 +167,7 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per
vm_manager.Reprotect(vma, perms);
heap_used += size;
+ memory_region->used += size;
return MakeResult<VAddr>(heap_end - size);
}
@@ -182,6 +185,7 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
if (result.IsError()) return result;
heap_used -= size;
+ memory_region->used -= size;
return RESULT_SUCCESS;
}
@@ -217,6 +221,7 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p
vm_manager.Reprotect(vma, perms);
linear_heap_used += size;
+ memory_region->used += size;
return MakeResult<VAddr>(target);
}
@@ -243,6 +248,7 @@ ResultCode Process::LinearFree(VAddr target, u32 size) {
if (result.IsError()) return result;
linear_heap_used -= size;
+ memory_region->used -= size;
if (target + size == heap_end) {
// End of linear heap has been freed, so check what's the last allocated block in it and
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 00fa995f6..c08fc1c7a 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -20,6 +20,7 @@
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h"
+#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/mutex.h"
#include "core/hle/result.h"
#include "core/memory.h"
@@ -118,6 +119,7 @@ void Thread::Stop() {
Kernel::g_current_process->used_tls_slots[tls_index] = false;
g_current_process->misc_memory_used -= Memory::TLS_ENTRY_SIZE;
+ g_current_process->memory_region->used -= Memory::TLS_ENTRY_SIZE;
HLE::Reschedule(__func__);
}
@@ -416,6 +418,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
ASSERT_MSG(thread->tls_index != -1, "Out of TLS space");
g_current_process->misc_memory_used += Memory::TLS_ENTRY_SIZE;
+ g_current_process->memory_region->used += Memory::TLS_ENTRY_SIZE;
// TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used
// to initialize the context
diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp
index ce2877f57..669659510 100644
--- a/src/core/hle/service/csnd_snd.cpp
+++ b/src/core/hle/service/csnd_snd.cpp
@@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cstring>
#include "core/hle/hle.h"
#include "core/hle/kernel/mutex.h"
#include "core/hle/kernel/shared_memory.h"
@@ -52,19 +53,19 @@ void Initialize(Service::Interface* self) {
}
void ExecuteType0Commands(Service::Interface* self) {
- u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32* const cmd_buff = Kernel::GetCommandBuffer();
+ u8* const ptr = shared_memory->GetPointer(cmd_buff[1]);
+
+ if (shared_memory != nullptr && ptr != nullptr) {
+ Type0Command command;
+ std::memcpy(&command, ptr, sizeof(Type0Command));
+
+ LOG_WARNING(Service, "(STUBBED) CSND_SND::ExecuteType0Commands");
+ command.finished |= 1;
+ cmd_buff[1] = 0;
- if (shared_memory != nullptr) {
- struct Type0Command* command = reinterpret_cast<struct Type0Command*>(
- shared_memory->GetPointer(cmd_buff[1]));
- if (command == nullptr) {
- cmd_buff[1] = 1;
- }else{
- LOG_WARNING(Service, "(STUBBED) CSND_SND::ExecuteType0Commands");
- command->finished |= 1;
- cmd_buff[1] = 0;
- }
- }else{
+ std::memcpy(ptr, &command, sizeof(Type0Command));
+ } else {
cmd_buff[1] = 1;
}
}
diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp
index 04ab194e6..cabd18c80 100644
--- a/src/core/hle/service/ssl_c.cpp
+++ b/src/core/hle/service/ssl_c.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <random>
+
#include "core/hle/hle.h"
#include "core/hle/service/ssl_c.h"
@@ -10,11 +12,58 @@
namespace SSL_C {
+// TODO: Implement a proper CSPRNG in the future when actual security is needed
+static std::mt19937 rand_gen;
+
+static void Initialize(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ // Seed random number generator when the SSL service is initialized
+ std::random_device rand_device;
+ rand_gen.seed(rand_device());
+
+ // Stub, return success
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+}
+
+static void GenerateRandomData(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 size = cmd_buff[1];
+ VAddr address = cmd_buff[3];
+ u8* output_buff = Memory::GetPointer(address);
+
+ // Fill the output buffer with random data.
+ u32 data = 0;
+ u32 i = 0;
+ while (i < size) {
+ if ((i % 4) == 0) {
+ // The random number generator returns 4 bytes worth of data, so generate new random data when i == 0 and when i is divisible by 4
+ data = rand_gen();
+ }
+
+ if (size > 4) {
+ // Use up the entire 4 bytes of the random data for as long as possible
+ *(u32*)(output_buff + i) = data;
+ i += 4;
+ } else if (size == 2) {
+ *(u16*)(output_buff + i) = (u16)(data & 0xffff);
+ i += 2;
+ } else {
+ *(u8*)(output_buff + i) = (u8)(data & 0xff);
+ i++;
+ }
+ }
+
+ // Stub, return success
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+}
+
const Interface::FunctionInfo FunctionTable[] = {
- {0x00010002, nullptr, "Initialize"},
+ {0x00010002, Initialize, "Initialize"},
{0x000200C2, nullptr, "CreateContext"},
{0x00050082, nullptr, "AddTrustedRootCA"},
- {0x00110042, nullptr, "GenerateRandomData"},
+ {0x00110042, GenerateRandomData, "GenerateRandomData"},
{0x00150082, nullptr, "Read"},
{0x00170082, nullptr, "Write"},
};
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 45d5f3c5d..7f63ff505 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -778,6 +778,51 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
return RESULT_SUCCESS;
}
+static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) {
+ using Kernel::MemoryRegion;
+
+ LOG_TRACE(Kernel_SVC, "called process=0x%08X type=%u param=%d", process_handle, type, param);
+
+ switch ((SystemInfoType)type) {
+ case SystemInfoType::REGION_MEMORY_USAGE:
+ switch ((SystemInfoMemUsageRegion)param) {
+ case SystemInfoMemUsageRegion::ALL:
+ *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used
+ + Kernel::GetMemoryRegion(Kernel::MemoryRegion::SYSTEM)->used
+ + Kernel::GetMemoryRegion(Kernel::MemoryRegion::BASE)->used;
+ break;
+ case SystemInfoMemUsageRegion::APPLICATION:
+ *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used;
+ break;
+ case SystemInfoMemUsageRegion::SYSTEM:
+ *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::SYSTEM)->used;
+ break;
+ case SystemInfoMemUsageRegion::BASE:
+ *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::BASE)->used;
+ break;
+ default:
+ LOG_ERROR(Kernel_SVC, "unknown GetSystemInfo type=0 region: param=%d", param);
+ *out = 0;
+ break;
+ }
+ break;
+ case SystemInfoType::KERNEL_ALLOCATED_PAGES:
+ LOG_ERROR(Kernel_SVC, "unimplemented GetSystemInfo type=2 param=%d", type, param);
+ *out = 0;
+ break;
+ case SystemInfoType::KERNEL_SPAWNED_PIDS:
+ *out = 5;
+ break;
+ default:
+ LOG_ERROR(Kernel_SVC, "unknown GetSystemInfo type=%u param=%d", type, param);
+ *out = 0;
+ break;
+ }
+
+ // This function never returns an error, even if invalid parameters were passed.
+ return RESULT_SUCCESS;
+}
+
static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) {
LOG_TRACE(Kernel_SVC, "called process=0x%08X type=%u", process_handle, type);
@@ -877,7 +922,7 @@ static const FunctionDef SVC_Table[] = {
{0x27, HLE::Wrap<DuplicateHandle>, "DuplicateHandle"},
{0x28, HLE::Wrap<GetSystemTick>, "GetSystemTick"},
{0x29, nullptr, "GetHandleInfo"},
- {0x2A, nullptr, "GetSystemInfo"},
+ {0x2A, HLE::Wrap<GetSystemInfo>, "GetSystemInfo"},
{0x2B, HLE::Wrap<GetProcessInfo>, "GetProcessInfo"},
{0x2C, nullptr, "GetThreadInfo"},
{0x2D, HLE::Wrap<ConnectToPort>, "ConnectToPort"},
diff --git a/src/core/hle/svc.h b/src/core/hle/svc.h
index 12de9ffbe..4b9c71e06 100644
--- a/src/core/hle/svc.h
+++ b/src/core/hle/svc.h
@@ -41,6 +41,35 @@ enum ArbitrationType {
namespace SVC {
+/// Values accepted by svcGetSystemInfo's type parameter.
+enum class SystemInfoType {
+ /**
+ * Reports total used memory for all regions or a specific one, according to the extra
+ * parameter. See `SystemInfoMemUsageRegion`.
+ */
+ REGION_MEMORY_USAGE = 0,
+ /**
+ * Returns the memory usage for certain allocations done internally by the kernel.
+ */
+ KERNEL_ALLOCATED_PAGES = 2,
+ /**
+ * "This returns the total number of processes which were launched directly by the kernel.
+ * For the ARM11 NATIVE_FIRM kernel, this is 5, for processes sm, fs, pm, loader, and pxi."
+ */
+ KERNEL_SPAWNED_PIDS = 26,
+};
+
+/**
+ * Accepted by svcGetSystemInfo param with REGION_MEMORY_USAGE type. Selects a region to query
+ * memory usage of.
+ */
+enum class SystemInfoMemUsageRegion {
+ ALL = 0,
+ APPLICATION = 1,
+ SYSTEM = 2,
+ BASE = 3,
+};
+
void CallSVC(u32 immediate);
} // namespace