diff options
| author | 2019-07-14 09:16:46 -0400 | |
|---|---|---|
| committer | 2019-07-14 09:16:46 -0400 | |
| commit | 4882c058fd4cab4a327f6ad106c217c0d8ce2011 (patch) | |
| tree | cd2021c0de2f077415959e4841c5aaea47bf0670 /src/core/hle/kernel/svc.cpp | |
| parent | Merge pull request #2692 from ReinUsesLisp/tlds-f16 (diff) | |
| parent | Remove unicorn mappings/unmappings (diff) | |
| download | yuzu-4882c058fd4cab4a327f6ad106c217c0d8ce2011.tar.gz yuzu-4882c058fd4cab4a327f6ad106c217c0d8ce2011.tar.xz yuzu-4882c058fd4cab4a327f6ad106c217c0d8ce2011.zip | |
Merge pull request #2690 from SciresM/physmem_fixes
Implement MapPhysicalMemory/UnmapPhysicalMemory
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 117 |
1 files changed, 101 insertions, 16 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 58374f829..a46eed3da 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -736,16 +736,16 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha | |||
| 736 | StackRegionBaseAddr = 14, | 736 | StackRegionBaseAddr = 14, |
| 737 | StackRegionSize = 15, | 737 | StackRegionSize = 15, |
| 738 | // 3.0.0+ | 738 | // 3.0.0+ |
| 739 | IsVirtualAddressMemoryEnabled = 16, | 739 | SystemResourceSize = 16, |
| 740 | PersonalMmHeapUsage = 17, | 740 | SystemResourceUsage = 17, |
| 741 | TitleId = 18, | 741 | TitleId = 18, |
| 742 | // 4.0.0+ | 742 | // 4.0.0+ |
| 743 | PrivilegedProcessId = 19, | 743 | PrivilegedProcessId = 19, |
| 744 | // 5.0.0+ | 744 | // 5.0.0+ |
| 745 | UserExceptionContextAddr = 20, | 745 | UserExceptionContextAddr = 20, |
| 746 | // 6.0.0+ | 746 | // 6.0.0+ |
| 747 | TotalPhysicalMemoryAvailableWithoutMmHeap = 21, | 747 | TotalPhysicalMemoryAvailableWithoutSystemResource = 21, |
| 748 | TotalPhysicalMemoryUsedWithoutMmHeap = 22, | 748 | TotalPhysicalMemoryUsedWithoutSystemResource = 22, |
| 749 | }; | 749 | }; |
| 750 | 750 | ||
| 751 | const auto info_id_type = static_cast<GetInfoType>(info_id); | 751 | const auto info_id_type = static_cast<GetInfoType>(info_id); |
| @@ -763,12 +763,12 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha | |||
| 763 | case GetInfoType::StackRegionSize: | 763 | case GetInfoType::StackRegionSize: |
| 764 | case GetInfoType::TotalPhysicalMemoryAvailable: | 764 | case GetInfoType::TotalPhysicalMemoryAvailable: |
| 765 | case GetInfoType::TotalPhysicalMemoryUsed: | 765 | case GetInfoType::TotalPhysicalMemoryUsed: |
| 766 | case GetInfoType::IsVirtualAddressMemoryEnabled: | 766 | case GetInfoType::SystemResourceSize: |
| 767 | case GetInfoType::PersonalMmHeapUsage: | 767 | case GetInfoType::SystemResourceUsage: |
| 768 | case GetInfoType::TitleId: | 768 | case GetInfoType::TitleId: |
| 769 | case GetInfoType::UserExceptionContextAddr: | 769 | case GetInfoType::UserExceptionContextAddr: |
| 770 | case GetInfoType::TotalPhysicalMemoryAvailableWithoutMmHeap: | 770 | case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource: |
| 771 | case GetInfoType::TotalPhysicalMemoryUsedWithoutMmHeap: { | 771 | case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource: { |
| 772 | if (info_sub_id != 0) { | 772 | if (info_sub_id != 0) { |
| 773 | return ERR_INVALID_ENUM_VALUE; | 773 | return ERR_INVALID_ENUM_VALUE; |
| 774 | } | 774 | } |
| @@ -829,8 +829,13 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha | |||
| 829 | *result = process->GetTotalPhysicalMemoryUsed(); | 829 | *result = process->GetTotalPhysicalMemoryUsed(); |
| 830 | return RESULT_SUCCESS; | 830 | return RESULT_SUCCESS; |
| 831 | 831 | ||
| 832 | case GetInfoType::IsVirtualAddressMemoryEnabled: | 832 | case GetInfoType::SystemResourceSize: |
| 833 | *result = process->IsVirtualMemoryEnabled(); | 833 | *result = process->GetSystemResourceSize(); |
| 834 | return RESULT_SUCCESS; | ||
| 835 | |||
| 836 | case GetInfoType::SystemResourceUsage: | ||
| 837 | LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query system resource usage"); | ||
| 838 | *result = process->GetSystemResourceUsage(); | ||
| 834 | return RESULT_SUCCESS; | 839 | return RESULT_SUCCESS; |
| 835 | 840 | ||
| 836 | case GetInfoType::TitleId: | 841 | case GetInfoType::TitleId: |
| @@ -843,12 +848,12 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha | |||
| 843 | *result = 0; | 848 | *result = 0; |
| 844 | return RESULT_SUCCESS; | 849 | return RESULT_SUCCESS; |
| 845 | 850 | ||
| 846 | case GetInfoType::TotalPhysicalMemoryAvailableWithoutMmHeap: | 851 | case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource: |
| 847 | *result = process->GetTotalPhysicalMemoryAvailable(); | 852 | *result = process->GetTotalPhysicalMemoryAvailableWithoutSystemResource(); |
| 848 | return RESULT_SUCCESS; | 853 | return RESULT_SUCCESS; |
| 849 | 854 | ||
| 850 | case GetInfoType::TotalPhysicalMemoryUsedWithoutMmHeap: | 855 | case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource: |
| 851 | *result = process->GetTotalPhysicalMemoryUsedWithoutMmHeap(); | 856 | *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource(); |
| 852 | return RESULT_SUCCESS; | 857 | return RESULT_SUCCESS; |
| 853 | 858 | ||
| 854 | default: | 859 | default: |
| @@ -953,6 +958,86 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha | |||
| 953 | } | 958 | } |
| 954 | } | 959 | } |
| 955 | 960 | ||
| 961 | /// Maps memory at a desired address | ||
| 962 | static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | ||
| 963 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | ||
| 964 | |||
| 965 | if (!Common::Is4KBAligned(addr)) { | ||
| 966 | LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, 0x{:016X}", addr); | ||
| 967 | return ERR_INVALID_ADDRESS; | ||
| 968 | } | ||
| 969 | |||
| 970 | if (!Common::Is4KBAligned(size)) { | ||
| 971 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:X}", size); | ||
| 972 | return ERR_INVALID_SIZE; | ||
| 973 | } | ||
| 974 | |||
| 975 | if (size == 0) { | ||
| 976 | LOG_ERROR(Kernel_SVC, "Size is zero"); | ||
| 977 | return ERR_INVALID_SIZE; | ||
| 978 | } | ||
| 979 | |||
| 980 | if (!(addr < addr + size)) { | ||
| 981 | LOG_ERROR(Kernel_SVC, "Size causes 64-bit overflow of address"); | ||
| 982 | return ERR_INVALID_MEMORY_RANGE; | ||
| 983 | } | ||
| 984 | |||
| 985 | Process* const current_process = system.Kernel().CurrentProcess(); | ||
| 986 | auto& vm_manager = current_process->VMManager(); | ||
| 987 | |||
| 988 | if (current_process->GetSystemResourceSize() == 0) { | ||
| 989 | LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); | ||
| 990 | return ERR_INVALID_STATE; | ||
| 991 | } | ||
| 992 | |||
| 993 | if (!vm_manager.IsWithinMapRegion(addr, size)) { | ||
| 994 | LOG_ERROR(Kernel_SVC, "Range not within map region"); | ||
| 995 | return ERR_INVALID_MEMORY_RANGE; | ||
| 996 | } | ||
| 997 | |||
| 998 | return vm_manager.MapPhysicalMemory(addr, size); | ||
| 999 | } | ||
| 1000 | |||
| 1001 | /// Unmaps memory previously mapped via MapPhysicalMemory | ||
| 1002 | static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) { | ||
| 1003 | LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size); | ||
| 1004 | |||
| 1005 | if (!Common::Is4KBAligned(addr)) { | ||
| 1006 | LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, 0x{:016X}", addr); | ||
| 1007 | return ERR_INVALID_ADDRESS; | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | if (!Common::Is4KBAligned(size)) { | ||
| 1011 | LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:X}", size); | ||
| 1012 | return ERR_INVALID_SIZE; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | if (size == 0) { | ||
| 1016 | LOG_ERROR(Kernel_SVC, "Size is zero"); | ||
| 1017 | return ERR_INVALID_SIZE; | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | if (!(addr < addr + size)) { | ||
| 1021 | LOG_ERROR(Kernel_SVC, "Size causes 64-bit overflow of address"); | ||
| 1022 | return ERR_INVALID_MEMORY_RANGE; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | Process* const current_process = system.Kernel().CurrentProcess(); | ||
| 1026 | auto& vm_manager = current_process->VMManager(); | ||
| 1027 | |||
| 1028 | if (current_process->GetSystemResourceSize() == 0) { | ||
| 1029 | LOG_ERROR(Kernel_SVC, "System Resource Size is zero"); | ||
| 1030 | return ERR_INVALID_STATE; | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | if (!vm_manager.IsWithinMapRegion(addr, size)) { | ||
| 1034 | LOG_ERROR(Kernel_SVC, "Range not within map region"); | ||
| 1035 | return ERR_INVALID_MEMORY_RANGE; | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | return vm_manager.UnmapPhysicalMemory(addr, size); | ||
| 1039 | } | ||
| 1040 | |||
| 956 | /// Sets the thread activity | 1041 | /// Sets the thread activity |
| 957 | static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) { | 1042 | static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) { |
| 958 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity); | 1043 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity); |
| @@ -2310,8 +2395,8 @@ static const FunctionDef SVC_Table[] = { | |||
| 2310 | {0x29, SvcWrap<GetInfo>, "GetInfo"}, | 2395 | {0x29, SvcWrap<GetInfo>, "GetInfo"}, |
| 2311 | {0x2A, nullptr, "FlushEntireDataCache"}, | 2396 | {0x2A, nullptr, "FlushEntireDataCache"}, |
| 2312 | {0x2B, nullptr, "FlushDataCache"}, | 2397 | {0x2B, nullptr, "FlushDataCache"}, |
| 2313 | {0x2C, nullptr, "MapPhysicalMemory"}, | 2398 | {0x2C, SvcWrap<MapPhysicalMemory>, "MapPhysicalMemory"}, |
| 2314 | {0x2D, nullptr, "UnmapPhysicalMemory"}, | 2399 | {0x2D, SvcWrap<UnmapPhysicalMemory>, "UnmapPhysicalMemory"}, |
| 2315 | {0x2E, nullptr, "GetFutureThreadInfo"}, | 2400 | {0x2E, nullptr, "GetFutureThreadInfo"}, |
| 2316 | {0x2F, nullptr, "GetLastThreadInfo"}, | 2401 | {0x2F, nullptr, "GetLastThreadInfo"}, |
| 2317 | {0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"}, | 2402 | {0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"}, |