summaryrefslogtreecommitdiffstats
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.cpp146
1 files changed, 119 insertions, 27 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index de6363ff2..a46eed3da 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -98,9 +98,9 @@ ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_add
return ERR_INVALID_ADDRESS_STATE;
}
- if (!vm_manager.IsWithinNewMapRegion(dst_addr, size)) {
+ if (!vm_manager.IsWithinStackRegion(dst_addr, size)) {
LOG_ERROR(Kernel_SVC,
- "Destination is not within the new map region, addr=0x{:016X}, size=0x{:016X}",
+ "Destination is not within the stack region, addr=0x{:016X}, size=0x{:016X}",
dst_addr, size);
return ERR_INVALID_MEMORY_RANGE;
}
@@ -318,7 +318,14 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad
return result;
}
- return vm_manager.UnmapRange(dst_addr, size);
+ const auto unmap_res = vm_manager.UnmapRange(dst_addr, size);
+
+ // Reprotect the source mapping on success
+ if (unmap_res.IsSuccess()) {
+ ASSERT(vm_manager.ReprotectRange(src_addr, size, VMAPermission::ReadWrite).IsSuccess());
+ }
+
+ return unmap_res;
}
/// Connect to an OS service given the port name, returns the handle to the port to out
@@ -726,19 +733,19 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
// 2.0.0+
ASLRRegionBaseAddr = 12,
ASLRRegionSize = 13,
- NewMapRegionBaseAddr = 14,
- NewMapRegionSize = 15,
+ StackRegionBaseAddr = 14,
+ StackRegionSize = 15,
// 3.0.0+
- IsVirtualAddressMemoryEnabled = 16,
- PersonalMmHeapUsage = 17,
+ SystemResourceSize = 16,
+ SystemResourceUsage = 17,
TitleId = 18,
// 4.0.0+
PrivilegedProcessId = 19,
// 5.0.0+
UserExceptionContextAddr = 20,
// 6.0.0+
- TotalPhysicalMemoryAvailableWithoutMmHeap = 21,
- TotalPhysicalMemoryUsedWithoutMmHeap = 22,
+ TotalPhysicalMemoryAvailableWithoutSystemResource = 21,
+ TotalPhysicalMemoryUsedWithoutSystemResource = 22,
};
const auto info_id_type = static_cast<GetInfoType>(info_id);
@@ -752,16 +759,16 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
case GetInfoType::HeapRegionSize:
case GetInfoType::ASLRRegionBaseAddr:
case GetInfoType::ASLRRegionSize:
- case GetInfoType::NewMapRegionBaseAddr:
- case GetInfoType::NewMapRegionSize:
+ case GetInfoType::StackRegionBaseAddr:
+ case GetInfoType::StackRegionSize:
case GetInfoType::TotalPhysicalMemoryAvailable:
case GetInfoType::TotalPhysicalMemoryUsed:
- case GetInfoType::IsVirtualAddressMemoryEnabled:
- case GetInfoType::PersonalMmHeapUsage:
+ case GetInfoType::SystemResourceSize:
+ case GetInfoType::SystemResourceUsage:
case GetInfoType::TitleId:
case GetInfoType::UserExceptionContextAddr:
- case GetInfoType::TotalPhysicalMemoryAvailableWithoutMmHeap:
- case GetInfoType::TotalPhysicalMemoryUsedWithoutMmHeap: {
+ case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource:
+ case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource: {
if (info_sub_id != 0) {
return ERR_INVALID_ENUM_VALUE;
}
@@ -806,12 +813,12 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
*result = process->VMManager().GetASLRRegionSize();
return RESULT_SUCCESS;
- case GetInfoType::NewMapRegionBaseAddr:
- *result = process->VMManager().GetNewMapRegionBaseAddress();
+ case GetInfoType::StackRegionBaseAddr:
+ *result = process->VMManager().GetStackRegionBaseAddress();
return RESULT_SUCCESS;
- case GetInfoType::NewMapRegionSize:
- *result = process->VMManager().GetNewMapRegionSize();
+ case GetInfoType::StackRegionSize:
+ *result = process->VMManager().GetStackRegionSize();
return RESULT_SUCCESS;
case GetInfoType::TotalPhysicalMemoryAvailable:
@@ -822,8 +829,13 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
*result = process->GetTotalPhysicalMemoryUsed();
return RESULT_SUCCESS;
- case GetInfoType::IsVirtualAddressMemoryEnabled:
- *result = process->IsVirtualMemoryEnabled();
+ case GetInfoType::SystemResourceSize:
+ *result = process->GetSystemResourceSize();
+ return RESULT_SUCCESS;
+
+ case GetInfoType::SystemResourceUsage:
+ LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query system resource usage");
+ *result = process->GetSystemResourceUsage();
return RESULT_SUCCESS;
case GetInfoType::TitleId:
@@ -836,12 +848,12 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
*result = 0;
return RESULT_SUCCESS;
- case GetInfoType::TotalPhysicalMemoryAvailableWithoutMmHeap:
- *result = process->GetTotalPhysicalMemoryAvailable();
+ case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource:
+ *result = process->GetTotalPhysicalMemoryAvailableWithoutSystemResource();
return RESULT_SUCCESS;
- case GetInfoType::TotalPhysicalMemoryUsedWithoutMmHeap:
- *result = process->GetTotalPhysicalMemoryUsedWithoutMmHeap();
+ case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource:
+ *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource();
return RESULT_SUCCESS;
default:
@@ -946,6 +958,86 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
}
}
+/// Maps memory at a desired address
+static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
+ LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
+
+ if (!Common::Is4KBAligned(addr)) {
+ LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, 0x{:016X}", addr);
+ return ERR_INVALID_ADDRESS;
+ }
+
+ if (!Common::Is4KBAligned(size)) {
+ LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:X}", size);
+ return ERR_INVALID_SIZE;
+ }
+
+ if (size == 0) {
+ LOG_ERROR(Kernel_SVC, "Size is zero");
+ return ERR_INVALID_SIZE;
+ }
+
+ if (!(addr < addr + size)) {
+ LOG_ERROR(Kernel_SVC, "Size causes 64-bit overflow of address");
+ return ERR_INVALID_MEMORY_RANGE;
+ }
+
+ Process* const current_process = system.Kernel().CurrentProcess();
+ auto& vm_manager = current_process->VMManager();
+
+ if (current_process->GetSystemResourceSize() == 0) {
+ LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
+ return ERR_INVALID_STATE;
+ }
+
+ if (!vm_manager.IsWithinMapRegion(addr, size)) {
+ LOG_ERROR(Kernel_SVC, "Range not within map region");
+ return ERR_INVALID_MEMORY_RANGE;
+ }
+
+ return vm_manager.MapPhysicalMemory(addr, size);
+}
+
+/// Unmaps memory previously mapped via MapPhysicalMemory
+static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
+ LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
+
+ if (!Common::Is4KBAligned(addr)) {
+ LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, 0x{:016X}", addr);
+ return ERR_INVALID_ADDRESS;
+ }
+
+ if (!Common::Is4KBAligned(size)) {
+ LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, 0x{:X}", size);
+ return ERR_INVALID_SIZE;
+ }
+
+ if (size == 0) {
+ LOG_ERROR(Kernel_SVC, "Size is zero");
+ return ERR_INVALID_SIZE;
+ }
+
+ if (!(addr < addr + size)) {
+ LOG_ERROR(Kernel_SVC, "Size causes 64-bit overflow of address");
+ return ERR_INVALID_MEMORY_RANGE;
+ }
+
+ Process* const current_process = system.Kernel().CurrentProcess();
+ auto& vm_manager = current_process->VMManager();
+
+ if (current_process->GetSystemResourceSize() == 0) {
+ LOG_ERROR(Kernel_SVC, "System Resource Size is zero");
+ return ERR_INVALID_STATE;
+ }
+
+ if (!vm_manager.IsWithinMapRegion(addr, size)) {
+ LOG_ERROR(Kernel_SVC, "Range not within map region");
+ return ERR_INVALID_MEMORY_RANGE;
+ }
+
+ return vm_manager.UnmapPhysicalMemory(addr, size);
+}
+
/// Sets the thread activity
static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 activity) {
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", handle, activity);
@@ -2303,8 +2395,8 @@ static const FunctionDef SVC_Table[] = {
{0x29, SvcWrap<GetInfo>, "GetInfo"},
{0x2A, nullptr, "FlushEntireDataCache"},
{0x2B, nullptr, "FlushDataCache"},
- {0x2C, nullptr, "MapPhysicalMemory"},
- {0x2D, nullptr, "UnmapPhysicalMemory"},
+ {0x2C, SvcWrap<MapPhysicalMemory>, "MapPhysicalMemory"},
+ {0x2D, SvcWrap<UnmapPhysicalMemory>, "UnmapPhysicalMemory"},
{0x2E, nullptr, "GetFutureThreadInfo"},
{0x2F, nullptr, "GetLastThreadInfo"},
{0x30, SvcWrap<GetResourceLimitLimitValue>, "GetResourceLimitLimitValue"},