diff options
| author | 2015-11-30 21:17:34 -0800 | |
|---|---|---|
| committer | 2015-11-30 21:17:34 -0800 | |
| commit | bec90495976ad5bca6feb514888880d755c52b1b (patch) | |
| tree | 928497d2056d1c5ea719ac0cb359888b0df4d6bc | |
| parent | Merge pull request #1259 from lioncash/zero (diff) | |
| parent | Kernel: Implement svcGetSystemInfo (diff) | |
| download | yuzu-bec90495976ad5bca6feb514888880d755c52b1b.tar.gz yuzu-bec90495976ad5bca6feb514888880d755c52b1b.tar.xz yuzu-bec90495976ad5bca6feb514888880d755c52b1b.zip | |
Merge pull request #1257 from yuriks/svcGetSystemInfo
Kernel: Implement svcGetSystemInfo
| -rw-r--r-- | src/core/hle/function_wrappers.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/memory.h | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 47 | ||||
| -rw-r--r-- | src/core/hle/svc.h | 29 |
7 files changed, 95 insertions, 1 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() { | |||
| 159 | FuncReturn(retval); | 159 | FuncReturn(retval); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | template<ResultCode func(s64*, u32, s32)> void Wrap() { | ||
| 163 | s64 param_1 = 0; | ||
| 164 | u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw; | ||
| 165 | Core::g_app_core->SetReg(1, (u32)param_1); | ||
| 166 | Core::g_app_core->SetReg(2, (u32)(param_1 >> 32)); | ||
| 167 | FuncReturn(retval); | ||
| 168 | } | ||
| 169 | |||
| 162 | template<ResultCode func(u32*, u32, u32, u32, u32)> void Wrap() { | 170 | template<ResultCode func(u32*, u32, u32, u32, u32)> void Wrap() { |
| 163 | u32 param_1 = 0; | 171 | u32 param_1 = 0; |
| 164 | u32 retval = func(¶m_1, PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw; | 172 | u32 retval = func(¶m_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) { | |||
| 51 | for (int i = 0; i < 3; ++i) { | 51 | for (int i = 0; i < 3; ++i) { |
| 52 | memory_regions[i].base = base; | 52 | memory_regions[i].base = base; |
| 53 | memory_regions[i].size = memory_region_sizes[mem_type][i]; | 53 | memory_regions[i].size = memory_region_sizes[mem_type][i]; |
| 54 | memory_regions[i].used = 0; | ||
| 54 | memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>(); | 55 | memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>(); |
| 55 | 56 | ||
| 56 | base += memory_regions[i].size; | 57 | base += memory_regions[i].size; |
| @@ -72,6 +73,7 @@ void MemoryShutdown() { | |||
| 72 | for (auto& region : memory_regions) { | 73 | for (auto& region : memory_regions) { |
| 73 | region.base = 0; | 74 | region.base = 0; |
| 74 | region.size = 0; | 75 | region.size = 0; |
| 76 | region.used = 0; | ||
| 75 | region.linear_heap_memory = nullptr; | 77 | region.linear_heap_memory = nullptr; |
| 76 | } | 78 | } |
| 77 | } | 79 | } |
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; | |||
| 17 | struct MemoryRegionInfo { | 17 | struct MemoryRegionInfo { |
| 18 | u32 base; // Not an address, but offset from start of FCRAM | 18 | u32 base; // Not an address, but offset from start of FCRAM |
| 19 | u32 size; | 19 | u32 size; |
| 20 | u32 used; | ||
| 20 | 21 | ||
| 21 | std::shared_ptr<std::vector<u8>> linear_heap_memory; | 22 | std::shared_ptr<std::vector<u8>> linear_heap_memory; |
| 22 | }; | 23 | }; |
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) { | |||
| 111 | segment.offset, segment.size, memory_state).Unwrap(); | 111 | segment.offset, segment.size, memory_state).Unwrap(); |
| 112 | vm_manager.Reprotect(vma, permissions); | 112 | vm_manager.Reprotect(vma, permissions); |
| 113 | misc_memory_used += segment.size; | 113 | misc_memory_used += segment.size; |
| 114 | memory_region->used += segment.size; | ||
| 114 | }; | 115 | }; |
| 115 | 116 | ||
| 116 | // Map CodeSet segments | 117 | // Map CodeSet segments |
| @@ -123,6 +124,7 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) { | |||
| 123 | std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, MemoryState::Locked | 124 | std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, MemoryState::Locked |
| 124 | ).Unwrap(); | 125 | ).Unwrap(); |
| 125 | misc_memory_used += stack_size; | 126 | misc_memory_used += stack_size; |
| 127 | memory_region->used += stack_size; | ||
| 126 | 128 | ||
| 127 | vm_manager.LogLayout(Log::Level::Debug); | 129 | vm_manager.LogLayout(Log::Level::Debug); |
| 128 | Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority); | 130 | Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority); |
| @@ -165,6 +167,7 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per | |||
| 165 | vm_manager.Reprotect(vma, perms); | 167 | vm_manager.Reprotect(vma, perms); |
| 166 | 168 | ||
| 167 | heap_used += size; | 169 | heap_used += size; |
| 170 | memory_region->used += size; | ||
| 168 | 171 | ||
| 169 | return MakeResult<VAddr>(heap_end - size); | 172 | return MakeResult<VAddr>(heap_end - size); |
| 170 | } | 173 | } |
| @@ -182,6 +185,7 @@ ResultCode Process::HeapFree(VAddr target, u32 size) { | |||
| 182 | if (result.IsError()) return result; | 185 | if (result.IsError()) return result; |
| 183 | 186 | ||
| 184 | heap_used -= size; | 187 | heap_used -= size; |
| 188 | memory_region->used -= size; | ||
| 185 | 189 | ||
| 186 | return RESULT_SUCCESS; | 190 | return RESULT_SUCCESS; |
| 187 | } | 191 | } |
| @@ -217,6 +221,7 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p | |||
| 217 | vm_manager.Reprotect(vma, perms); | 221 | vm_manager.Reprotect(vma, perms); |
| 218 | 222 | ||
| 219 | linear_heap_used += size; | 223 | linear_heap_used += size; |
| 224 | memory_region->used += size; | ||
| 220 | 225 | ||
| 221 | return MakeResult<VAddr>(target); | 226 | return MakeResult<VAddr>(target); |
| 222 | } | 227 | } |
| @@ -243,6 +248,7 @@ ResultCode Process::LinearFree(VAddr target, u32 size) { | |||
| 243 | if (result.IsError()) return result; | 248 | if (result.IsError()) return result; |
| 244 | 249 | ||
| 245 | linear_heap_used -= size; | 250 | linear_heap_used -= size; |
| 251 | memory_region->used -= size; | ||
| 246 | 252 | ||
| 247 | if (target + size == heap_end) { | 253 | if (target + size == heap_end) { |
| 248 | // End of linear heap has been freed, so check what's the last allocated block in it and | 254 | // 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 @@ | |||
| 20 | #include "core/hle/kernel/kernel.h" | 20 | #include "core/hle/kernel/kernel.h" |
| 21 | #include "core/hle/kernel/process.h" | 21 | #include "core/hle/kernel/process.h" |
| 22 | #include "core/hle/kernel/thread.h" | 22 | #include "core/hle/kernel/thread.h" |
| 23 | #include "core/hle/kernel/memory.h" | ||
| 23 | #include "core/hle/kernel/mutex.h" | 24 | #include "core/hle/kernel/mutex.h" |
| 24 | #include "core/hle/result.h" | 25 | #include "core/hle/result.h" |
| 25 | #include "core/memory.h" | 26 | #include "core/memory.h" |
| @@ -118,6 +119,7 @@ void Thread::Stop() { | |||
| 118 | 119 | ||
| 119 | Kernel::g_current_process->used_tls_slots[tls_index] = false; | 120 | Kernel::g_current_process->used_tls_slots[tls_index] = false; |
| 120 | g_current_process->misc_memory_used -= Memory::TLS_ENTRY_SIZE; | 121 | g_current_process->misc_memory_used -= Memory::TLS_ENTRY_SIZE; |
| 122 | g_current_process->memory_region->used -= Memory::TLS_ENTRY_SIZE; | ||
| 121 | 123 | ||
| 122 | HLE::Reschedule(__func__); | 124 | HLE::Reschedule(__func__); |
| 123 | } | 125 | } |
| @@ -416,6 +418,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 416 | 418 | ||
| 417 | ASSERT_MSG(thread->tls_index != -1, "Out of TLS space"); | 419 | ASSERT_MSG(thread->tls_index != -1, "Out of TLS space"); |
| 418 | g_current_process->misc_memory_used += Memory::TLS_ENTRY_SIZE; | 420 | g_current_process->misc_memory_used += Memory::TLS_ENTRY_SIZE; |
| 421 | g_current_process->memory_region->used += Memory::TLS_ENTRY_SIZE; | ||
| 419 | 422 | ||
| 420 | // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used | 423 | // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used |
| 421 | // to initialize the context | 424 | // to initialize the context |
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 | |||
| 778 | return RESULT_SUCCESS; | 778 | return RESULT_SUCCESS; |
| 779 | } | 779 | } |
| 780 | 780 | ||
| 781 | static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) { | ||
| 782 | using Kernel::MemoryRegion; | ||
| 783 | |||
| 784 | LOG_TRACE(Kernel_SVC, "called process=0x%08X type=%u param=%d", process_handle, type, param); | ||
| 785 | |||
| 786 | switch ((SystemInfoType)type) { | ||
| 787 | case SystemInfoType::REGION_MEMORY_USAGE: | ||
| 788 | switch ((SystemInfoMemUsageRegion)param) { | ||
| 789 | case SystemInfoMemUsageRegion::ALL: | ||
| 790 | *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used | ||
| 791 | + Kernel::GetMemoryRegion(Kernel::MemoryRegion::SYSTEM)->used | ||
| 792 | + Kernel::GetMemoryRegion(Kernel::MemoryRegion::BASE)->used; | ||
| 793 | break; | ||
| 794 | case SystemInfoMemUsageRegion::APPLICATION: | ||
| 795 | *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used; | ||
| 796 | break; | ||
| 797 | case SystemInfoMemUsageRegion::SYSTEM: | ||
| 798 | *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::SYSTEM)->used; | ||
| 799 | break; | ||
| 800 | case SystemInfoMemUsageRegion::BASE: | ||
| 801 | *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::BASE)->used; | ||
| 802 | break; | ||
| 803 | default: | ||
| 804 | LOG_ERROR(Kernel_SVC, "unknown GetSystemInfo type=0 region: param=%d", param); | ||
| 805 | *out = 0; | ||
| 806 | break; | ||
| 807 | } | ||
| 808 | break; | ||
| 809 | case SystemInfoType::KERNEL_ALLOCATED_PAGES: | ||
| 810 | LOG_ERROR(Kernel_SVC, "unimplemented GetSystemInfo type=2 param=%d", type, param); | ||
| 811 | *out = 0; | ||
| 812 | break; | ||
| 813 | case SystemInfoType::KERNEL_SPAWNED_PIDS: | ||
| 814 | *out = 5; | ||
| 815 | break; | ||
| 816 | default: | ||
| 817 | LOG_ERROR(Kernel_SVC, "unknown GetSystemInfo type=%u param=%d", type, param); | ||
| 818 | *out = 0; | ||
| 819 | break; | ||
| 820 | } | ||
| 821 | |||
| 822 | // This function never returns an error, even if invalid parameters were passed. | ||
| 823 | return RESULT_SUCCESS; | ||
| 824 | } | ||
| 825 | |||
| 781 | static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) { | 826 | static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) { |
| 782 | LOG_TRACE(Kernel_SVC, "called process=0x%08X type=%u", process_handle, type); | 827 | LOG_TRACE(Kernel_SVC, "called process=0x%08X type=%u", process_handle, type); |
| 783 | 828 | ||
| @@ -877,7 +922,7 @@ static const FunctionDef SVC_Table[] = { | |||
| 877 | {0x27, HLE::Wrap<DuplicateHandle>, "DuplicateHandle"}, | 922 | {0x27, HLE::Wrap<DuplicateHandle>, "DuplicateHandle"}, |
| 878 | {0x28, HLE::Wrap<GetSystemTick>, "GetSystemTick"}, | 923 | {0x28, HLE::Wrap<GetSystemTick>, "GetSystemTick"}, |
| 879 | {0x29, nullptr, "GetHandleInfo"}, | 924 | {0x29, nullptr, "GetHandleInfo"}, |
| 880 | {0x2A, nullptr, "GetSystemInfo"}, | 925 | {0x2A, HLE::Wrap<GetSystemInfo>, "GetSystemInfo"}, |
| 881 | {0x2B, HLE::Wrap<GetProcessInfo>, "GetProcessInfo"}, | 926 | {0x2B, HLE::Wrap<GetProcessInfo>, "GetProcessInfo"}, |
| 882 | {0x2C, nullptr, "GetThreadInfo"}, | 927 | {0x2C, nullptr, "GetThreadInfo"}, |
| 883 | {0x2D, HLE::Wrap<ConnectToPort>, "ConnectToPort"}, | 928 | {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 { | |||
| 41 | 41 | ||
| 42 | namespace SVC { | 42 | namespace SVC { |
| 43 | 43 | ||
| 44 | /// Values accepted by svcGetSystemInfo's type parameter. | ||
| 45 | enum class SystemInfoType { | ||
| 46 | /** | ||
| 47 | * Reports total used memory for all regions or a specific one, according to the extra | ||
| 48 | * parameter. See `SystemInfoMemUsageRegion`. | ||
| 49 | */ | ||
| 50 | REGION_MEMORY_USAGE = 0, | ||
| 51 | /** | ||
| 52 | * Returns the memory usage for certain allocations done internally by the kernel. | ||
| 53 | */ | ||
| 54 | KERNEL_ALLOCATED_PAGES = 2, | ||
| 55 | /** | ||
| 56 | * "This returns the total number of processes which were launched directly by the kernel. | ||
| 57 | * For the ARM11 NATIVE_FIRM kernel, this is 5, for processes sm, fs, pm, loader, and pxi." | ||
| 58 | */ | ||
| 59 | KERNEL_SPAWNED_PIDS = 26, | ||
| 60 | }; | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Accepted by svcGetSystemInfo param with REGION_MEMORY_USAGE type. Selects a region to query | ||
| 64 | * memory usage of. | ||
| 65 | */ | ||
| 66 | enum class SystemInfoMemUsageRegion { | ||
| 67 | ALL = 0, | ||
| 68 | APPLICATION = 1, | ||
| 69 | SYSTEM = 2, | ||
| 70 | BASE = 3, | ||
| 71 | }; | ||
| 72 | |||
| 44 | void CallSVC(u32 immediate); | 73 | void CallSVC(u32 immediate); |
| 45 | 74 | ||
| 46 | } // namespace | 75 | } // namespace |