summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp110
1 files changed, 102 insertions, 8 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 332573a95..abb374892 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -729,8 +729,8 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
729 StackRegionBaseAddr = 14, 729 StackRegionBaseAddr = 14,
730 StackRegionSize = 15, 730 StackRegionSize = 15,
731 // 3.0.0+ 731 // 3.0.0+
732 IsVirtualAddressMemoryEnabled = 16, 732 SystemResourceSize = 16,
733 PersonalMmHeapUsage = 17, 733 SystemResourceUsage = 17,
734 TitleId = 18, 734 TitleId = 18,
735 // 4.0.0+ 735 // 4.0.0+
736 PrivilegedProcessId = 19, 736 PrivilegedProcessId = 19,
@@ -756,8 +756,8 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
756 case GetInfoType::StackRegionSize: 756 case GetInfoType::StackRegionSize:
757 case GetInfoType::TotalPhysicalMemoryAvailable: 757 case GetInfoType::TotalPhysicalMemoryAvailable:
758 case GetInfoType::TotalPhysicalMemoryUsed: 758 case GetInfoType::TotalPhysicalMemoryUsed:
759 case GetInfoType::IsVirtualAddressMemoryEnabled: 759 case GetInfoType::SystemResourceSize:
760 case GetInfoType::PersonalMmHeapUsage: 760 case GetInfoType::SystemResourceUsage:
761 case GetInfoType::TitleId: 761 case GetInfoType::TitleId:
762 case GetInfoType::UserExceptionContextAddr: 762 case GetInfoType::UserExceptionContextAddr:
763 case GetInfoType::TotalPhysicalMemoryAvailableWithoutMmHeap: 763 case GetInfoType::TotalPhysicalMemoryAvailableWithoutMmHeap:
@@ -822,8 +822,22 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
822 *result = process->GetTotalPhysicalMemoryUsed(); 822 *result = process->GetTotalPhysicalMemoryUsed();
823 return RESULT_SUCCESS; 823 return RESULT_SUCCESS;
824 824
825 case GetInfoType::IsVirtualAddressMemoryEnabled: 825 case GetInfoType::SystemResourceSize:
826 *result = process->IsVirtualMemoryEnabled(); 826 *result = process->GetSystemResourceSize();
827 return RESULT_SUCCESS;
828
829 case GetInfoType::SystemResourceUsage:
830 // On hardware, this returns the amount of system resource memory that has
831 // been used by the kernel. This is problematic for Yuzu to emulate, because
832 // system resource memory is used for page tables -- and yuzu doesn't really
833 // have a way to calculate how much memory is required for page tables for
834 // the current process at any given time.
835 // TODO: Is this even worth implementing? No game should ever use it, since
836 // the amount of remaining page table space should never be relevant except
837 // for diagnostics. Is returning a value other than zero wise?
838 LOG_WARNING(Kernel_SVC,
839 "(STUBBED) Attempted to query system resource usage, returned 0");
840 *result = 0;
827 return RESULT_SUCCESS; 841 return RESULT_SUCCESS;
828 842
829 case GetInfoType::TitleId: 843 case GetInfoType::TitleId:
@@ -946,6 +960,86 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
946 } 960 }
947} 961}
948 962
963/// Maps memory at a desired address
964static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
965 LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
966
967 if (!Common::Is4KBAligned(addr)) {
968 LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, 0x{:016X}", addr);
969 return ERR_INVALID_ADDRESS;
970 }
971
972 if (!Common::Is4KBAligned(size)) {
973 LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:X}", size);
974 return ERR_INVALID_SIZE;
975 }
976
977 if (size == 0) {
978 LOG_ERROR(Kernel_SVC, "Size is zero");
979 return ERR_INVALID_SIZE;
980 }
981
982 if (!(addr < addr + size)) {
983 LOG_ERROR(Kernel_SVC, "Size causes 64-bit overflow of address");
984 return ERR_INVALID_MEMORY_RANGE;
985 }
986
987 auto* const current_process = Core::CurrentProcess();
988 auto& vm_manager = current_process->VMManager();
989
990 if (current_process->GetSystemResourceSize() == 0) {
991 LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
992 return ERR_INVALID_STATE;
993 }
994
995 if (!vm_manager.IsWithinMapRegion(addr, size)) {
996 LOG_ERROR(Kernel_SVC, "Range not within map region");
997 return ERR_INVALID_MEMORY_RANGE;
998 }
999
1000 return vm_manager.MapPhysicalMemory(addr, size);
1001}
1002
1003/// Unmaps memory previously mapped via MapPhysicalMemory
1004static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
1005 LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
1006
1007 if (!Common::Is4KBAligned(addr)) {
1008 LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, 0x{:016X}", addr);
1009 return ERR_INVALID_ADDRESS;
1010 }
1011
1012 if (!Common::Is4KBAligned(size)) {
1013 LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:X}", size);
1014 return ERR_INVALID_SIZE;
1015 }
1016
1017 if (size == 0) {
1018 LOG_ERROR(Kernel_SVC, "Size is zero");
1019 return ERR_INVALID_SIZE;
1020 }
1021
1022 if (!(addr < addr + size)) {
1023 LOG_ERROR(Kernel_SVC, "Size causes 64-bit overflow of address");
1024 return ERR_INVALID_MEMORY_RANGE;
1025 }
1026
1027 auto* const current_process = Core::CurrentProcess();
1028 auto& vm_manager = current_process->VMManager();
1029
1030 if (current_process->GetSystemResourceSize() == 0) {
1031 LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
1032 return ERR_INVALID_STATE;
1033 }
1034
1035 if (!vm_manager.IsWithinMapRegion(addr, size)) {
1036 LOG_ERROR(Kernel_SVC, "Range not within map region");
1037 return ERR_INVALID_MEMORY_RANGE;
1038 }
1039
1040 return vm_manager.UnmapPhysicalMemory(addr, size);
1041}
1042
949/// Sets the thread activity 1043/// Sets the thread activity
950static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) { 1044static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) {
951 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity); 1045 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity);
@@ -2303,8 +2397,8 @@ static const FunctionDef SVC_Table[] = {
2303 {0x29, SvcWrap<GetInfo>, "GetInfo"}, 2397 {0x29, SvcWrap<GetInfo>, "GetInfo"},
2304 {0x2A, nullptr, "FlushEntireDataCache"}, 2398 {0x2A, nullptr, "FlushEntireDataCache"},
2305 {0x2B, nullptr, "FlushDataCache"}, 2399 {0x2B, nullptr, "FlushDataCache"},
2306 {0x2C, nullptr, "MapPhysicalMemory"}, 2400 {0x2C, SvcWrap<MapPhysicalMemory>, "MapPhysicalMemory"},
2307 {0x2D, nullptr, "UnmapPhysicalMemory"}, 2401 {0x2D, SvcWrap<UnmapPhysicalMemory>, "UnmapPhysicalMemory"},
2308 {0x2E, nullptr, "GetFutureThreadInfo"}, 2402 {0x2E, nullptr, "GetFutureThreadInfo"},
2309 {0x2F, nullptr, "GetLastThreadInfo"}, 2403 {0x2F, nullptr, "GetLastThreadInfo"},
2310 {0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"}, 2404 {0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"},