diff options
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9928b3a26..db3ae3eb8 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -332,7 +332,9 @@ static ResultCode UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_ad | |||
| 332 | /// Connect to an OS service given the port name, returns the handle to the port to out | 332 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 333 | static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | 333 | static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, |
| 334 | VAddr port_name_address) { | 334 | VAddr port_name_address) { |
| 335 | if (!Memory::IsValidVirtualAddress(port_name_address)) { | 335 | auto& memory = system.Memory(); |
| 336 | |||
| 337 | if (!memory.IsValidVirtualAddress(port_name_address)) { | ||
| 336 | LOG_ERROR(Kernel_SVC, | 338 | LOG_ERROR(Kernel_SVC, |
| 337 | "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", | 339 | "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", |
| 338 | port_name_address); | 340 | port_name_address); |
| @@ -341,7 +343,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | |||
| 341 | 343 | ||
| 342 | static constexpr std::size_t PortNameMaxLength = 11; | 344 | static constexpr std::size_t PortNameMaxLength = 11; |
| 343 | // Read 1 char beyond the max allowed port name to detect names that are too long. | 345 | // Read 1 char beyond the max allowed port name to detect names that are too long. |
| 344 | std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1); | 346 | const std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1); |
| 345 | if (port_name.size() > PortNameMaxLength) { | 347 | if (port_name.size() > PortNameMaxLength) { |
| 346 | LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength, | 348 | LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength, |
| 347 | port_name.size()); | 349 | port_name.size()); |
| @@ -383,7 +385,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | |||
| 383 | 385 | ||
| 384 | // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server | 386 | // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server |
| 385 | // responds and cause a reschedule. | 387 | // responds and cause a reschedule. |
| 386 | return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread()); | 388 | return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread(), system.Memory()); |
| 387 | } | 389 | } |
| 388 | 390 | ||
| 389 | /// Get the ID for the specified thread. | 391 | /// Get the ID for the specified thread. |
| @@ -452,7 +454,8 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | |||
| 452 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", | 454 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", |
| 453 | handles_address, handle_count, nano_seconds); | 455 | handles_address, handle_count, nano_seconds); |
| 454 | 456 | ||
| 455 | if (!Memory::IsValidVirtualAddress(handles_address)) { | 457 | auto& memory = system.Memory(); |
| 458 | if (!memory.IsValidVirtualAddress(handles_address)) { | ||
| 456 | LOG_ERROR(Kernel_SVC, | 459 | LOG_ERROR(Kernel_SVC, |
| 457 | "Handle address is not a valid virtual address, handle_address=0x{:016X}", | 460 | "Handle address is not a valid virtual address, handle_address=0x{:016X}", |
| 458 | handles_address); | 461 | handles_address); |
| @@ -474,7 +477,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | |||
| 474 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 477 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 475 | 478 | ||
| 476 | for (u64 i = 0; i < handle_count; ++i) { | 479 | for (u64 i = 0; i < handle_count; ++i) { |
| 477 | const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); | 480 | const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); |
| 478 | const auto object = handle_table.Get<WaitObject>(handle); | 481 | const auto object = handle_table.Get<WaitObject>(handle); |
| 479 | 482 | ||
| 480 | if (object == nullptr) { | 483 | if (object == nullptr) { |
| @@ -616,13 +619,15 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { | |||
| 616 | return; | 619 | return; |
| 617 | } | 620 | } |
| 618 | 621 | ||
| 622 | auto& memory = system.Memory(); | ||
| 623 | |||
| 619 | // This typically is an error code so we're going to assume this is the case | 624 | // This typically is an error code so we're going to assume this is the case |
| 620 | if (sz == sizeof(u32)) { | 625 | if (sz == sizeof(u32)) { |
| 621 | LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", Memory::Read32(addr)); | 626 | LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", memory.Read32(addr)); |
| 622 | } else { | 627 | } else { |
| 623 | // We don't know what's in here so we'll hexdump it | 628 | // We don't know what's in here so we'll hexdump it |
| 624 | debug_buffer.resize(sz); | 629 | debug_buffer.resize(sz); |
| 625 | Memory::ReadBlock(addr, debug_buffer.data(), sz); | 630 | memory.ReadBlock(addr, debug_buffer.data(), sz); |
| 626 | std::string hexdump; | 631 | std::string hexdump; |
| 627 | for (std::size_t i = 0; i < debug_buffer.size(); i++) { | 632 | for (std::size_t i = 0; i < debug_buffer.size(); i++) { |
| 628 | hexdump += fmt::format("{:02X} ", debug_buffer[i]); | 633 | hexdump += fmt::format("{:02X} ", debug_buffer[i]); |
| @@ -712,7 +717,7 @@ static void OutputDebugString([[maybe_unused]] Core::System& system, VAddr addre | |||
| 712 | } | 717 | } |
| 713 | 718 | ||
| 714 | std::string str(len, '\0'); | 719 | std::string str(len, '\0'); |
| 715 | Memory::ReadBlock(address, str.data(), str.size()); | 720 | system.Memory().ReadBlock(address, str.data(), str.size()); |
| 716 | LOG_DEBUG(Debug_Emulated, "{}", str); | 721 | LOG_DEBUG(Debug_Emulated, "{}", str); |
| 717 | } | 722 | } |
| 718 | 723 | ||
| @@ -1115,7 +1120,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H | |||
| 1115 | std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{}); | 1120 | std::fill(ctx.vector_registers.begin() + 16, ctx.vector_registers.end(), u128{}); |
| 1116 | } | 1121 | } |
| 1117 | 1122 | ||
| 1118 | Memory::WriteBlock(thread_context, &ctx, sizeof(ctx)); | 1123 | system.Memory().WriteBlock(thread_context, &ctx, sizeof(ctx)); |
| 1119 | return RESULT_SUCCESS; | 1124 | return RESULT_SUCCESS; |
| 1120 | } | 1125 | } |
| 1121 | 1126 | ||
| @@ -1275,20 +1280,21 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add | |||
| 1275 | return ERR_INVALID_HANDLE; | 1280 | return ERR_INVALID_HANDLE; |
| 1276 | } | 1281 | } |
| 1277 | 1282 | ||
| 1283 | auto& memory = system.Memory(); | ||
| 1278 | const auto& vm_manager = process->VMManager(); | 1284 | const auto& vm_manager = process->VMManager(); |
| 1279 | const MemoryInfo memory_info = vm_manager.QueryMemory(address); | 1285 | const MemoryInfo memory_info = vm_manager.QueryMemory(address); |
| 1280 | 1286 | ||
| 1281 | Memory::Write64(memory_info_address, memory_info.base_address); | 1287 | memory.Write64(memory_info_address, memory_info.base_address); |
| 1282 | Memory::Write64(memory_info_address + 8, memory_info.size); | 1288 | memory.Write64(memory_info_address + 8, memory_info.size); |
| 1283 | Memory::Write32(memory_info_address + 16, memory_info.state); | 1289 | memory.Write32(memory_info_address + 16, memory_info.state); |
| 1284 | Memory::Write32(memory_info_address + 20, memory_info.attributes); | 1290 | memory.Write32(memory_info_address + 20, memory_info.attributes); |
| 1285 | Memory::Write32(memory_info_address + 24, memory_info.permission); | 1291 | memory.Write32(memory_info_address + 24, memory_info.permission); |
| 1286 | Memory::Write32(memory_info_address + 32, memory_info.ipc_ref_count); | 1292 | memory.Write32(memory_info_address + 32, memory_info.ipc_ref_count); |
| 1287 | Memory::Write32(memory_info_address + 28, memory_info.device_ref_count); | 1293 | memory.Write32(memory_info_address + 28, memory_info.device_ref_count); |
| 1288 | Memory::Write32(memory_info_address + 36, 0); | 1294 | memory.Write32(memory_info_address + 36, 0); |
| 1289 | 1295 | ||
| 1290 | // Page info appears to be currently unused by the kernel and is always set to zero. | 1296 | // Page info appears to be currently unused by the kernel and is always set to zero. |
| 1291 | Memory::Write32(page_info_address, 0); | 1297 | memory.Write32(page_info_address, 0); |
| 1292 | 1298 | ||
| 1293 | return RESULT_SUCCESS; | 1299 | return RESULT_SUCCESS; |
| 1294 | } | 1300 | } |
| @@ -1672,6 +1678,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var | |||
| 1672 | 1678 | ||
| 1673 | const std::size_t current_core = system.CurrentCoreIndex(); | 1679 | const std::size_t current_core = system.CurrentCoreIndex(); |
| 1674 | auto& monitor = system.Monitor(); | 1680 | auto& monitor = system.Monitor(); |
| 1681 | auto& memory = system.Memory(); | ||
| 1675 | 1682 | ||
| 1676 | // Atomically read the value of the mutex. | 1683 | // Atomically read the value of the mutex. |
| 1677 | u32 mutex_val = 0; | 1684 | u32 mutex_val = 0; |
| @@ -1681,7 +1688,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var | |||
| 1681 | monitor.SetExclusive(current_core, mutex_address); | 1688 | monitor.SetExclusive(current_core, mutex_address); |
| 1682 | 1689 | ||
| 1683 | // If the mutex is not yet acquired, acquire it. | 1690 | // If the mutex is not yet acquired, acquire it. |
| 1684 | mutex_val = Memory::Read32(mutex_address); | 1691 | mutex_val = memory.Read32(mutex_address); |
| 1685 | 1692 | ||
| 1686 | if (mutex_val != 0) { | 1693 | if (mutex_val != 0) { |
| 1687 | update_val = mutex_val | Mutex::MutexHasWaitersFlag; | 1694 | update_val = mutex_val | Mutex::MutexHasWaitersFlag; |
| @@ -2284,12 +2291,13 @@ static ResultCode GetProcessList(Core::System& system, u32* out_num_processes, | |||
| 2284 | return ERR_INVALID_ADDRESS_STATE; | 2291 | return ERR_INVALID_ADDRESS_STATE; |
| 2285 | } | 2292 | } |
| 2286 | 2293 | ||
| 2294 | auto& memory = system.Memory(); | ||
| 2287 | const auto& process_list = kernel.GetProcessList(); | 2295 | const auto& process_list = kernel.GetProcessList(); |
| 2288 | const auto num_processes = process_list.size(); | 2296 | const auto num_processes = process_list.size(); |
| 2289 | const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes); | 2297 | const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes); |
| 2290 | 2298 | ||
| 2291 | for (std::size_t i = 0; i < copy_amount; ++i) { | 2299 | for (std::size_t i = 0; i < copy_amount; ++i) { |
| 2292 | Memory::Write64(out_process_ids, process_list[i]->GetProcessID()); | 2300 | memory.Write64(out_process_ids, process_list[i]->GetProcessID()); |
| 2293 | out_process_ids += sizeof(u64); | 2301 | out_process_ids += sizeof(u64); |
| 2294 | } | 2302 | } |
| 2295 | 2303 | ||
| @@ -2323,13 +2331,14 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd | |||
| 2323 | return ERR_INVALID_ADDRESS_STATE; | 2331 | return ERR_INVALID_ADDRESS_STATE; |
| 2324 | } | 2332 | } |
| 2325 | 2333 | ||
| 2334 | auto& memory = system.Memory(); | ||
| 2326 | const auto& thread_list = current_process->GetThreadList(); | 2335 | const auto& thread_list = current_process->GetThreadList(); |
| 2327 | const auto num_threads = thread_list.size(); | 2336 | const auto num_threads = thread_list.size(); |
| 2328 | const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads); | 2337 | const auto copy_amount = std::min(std::size_t{out_thread_ids_size}, num_threads); |
| 2329 | 2338 | ||
| 2330 | auto list_iter = thread_list.cbegin(); | 2339 | auto list_iter = thread_list.cbegin(); |
| 2331 | for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) { | 2340 | for (std::size_t i = 0; i < copy_amount; ++i, ++list_iter) { |
| 2332 | Memory::Write64(out_thread_ids, (*list_iter)->GetThreadID()); | 2341 | memory.Write64(out_thread_ids, (*list_iter)->GetThreadID()); |
| 2333 | out_thread_ids += sizeof(u64); | 2342 | out_thread_ids += sizeof(u64); |
| 2334 | } | 2343 | } |
| 2335 | 2344 | ||