diff options
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/handle_table.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/init/init_slab_setup.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_page_table.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_transfer_memory.cpp | 45 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_transfer_memory.h | 82 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 93 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 12 |
8 files changed, 192 insertions, 53 deletions
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index ddb1e6fb2..9291f0a76 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp | |||
| @@ -59,7 +59,8 @@ ResultVal<Handle> HandleTable::Create(Object* obj) { | |||
| 59 | case HandleType::WritableEvent: | 59 | case HandleType::WritableEvent: |
| 60 | case HandleType::ClientSession: | 60 | case HandleType::ClientSession: |
| 61 | case HandleType::ServerSession: | 61 | case HandleType::ServerSession: |
| 62 | case HandleType::Session: { | 62 | case HandleType::Session: |
| 63 | case HandleType::TransferMemory: { | ||
| 63 | Handle handle{}; | 64 | Handle handle{}; |
| 64 | Add(&handle, reinterpret_cast<KAutoObject*>(obj), {}); | 65 | Add(&handle, reinterpret_cast<KAutoObject*>(obj), {}); |
| 65 | return MakeResult<Handle>(handle); | 66 | return MakeResult<Handle>(handle); |
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index 84d509d52..ce7a24c40 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "core/hle/kernel/k_memory_manager.h" | 14 | #include "core/hle/kernel/k_memory_manager.h" |
| 15 | #include "core/hle/kernel/k_session.h" | 15 | #include "core/hle/kernel/k_session.h" |
| 16 | #include "core/hle/kernel/k_shared_memory.h" | 16 | #include "core/hle/kernel/k_shared_memory.h" |
| 17 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 17 | #include "core/hle/kernel/k_system_control.h" | 18 | #include "core/hle/kernel/k_system_control.h" |
| 18 | #include "core/hle/kernel/k_thread.h" | 19 | #include "core/hle/kernel/k_thread.h" |
| 19 | #include "core/hle/kernel/memory_types.h" | 20 | #include "core/hle/kernel/memory_types.h" |
| @@ -28,6 +29,7 @@ namespace Kernel::Init { | |||
| 28 | HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \ | 29 | HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \ |
| 29 | HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \ | 30 | HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \ |
| 30 | HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \ | 31 | HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \ |
| 32 | HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \ | ||
| 31 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \ | 33 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \ |
| 32 | HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__) | 34 | HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__) |
| 33 | 35 | ||
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 49b824379..80a1586db 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h | |||
| @@ -216,8 +216,6 @@ public: | |||
| 216 | constexpr PAddr GetPhysicalAddr(VAddr addr) { | 216 | constexpr PAddr GetPhysicalAddr(VAddr addr) { |
| 217 | return page_table_impl.backing_addr[addr >> PageBits] + addr; | 217 | return page_table_impl.backing_addr[addr >> PageBits] + addr; |
| 218 | } | 218 | } |
| 219 | |||
| 220 | private: | ||
| 221 | constexpr bool Contains(VAddr addr) const { | 219 | constexpr bool Contains(VAddr addr) const { |
| 222 | return address_space_start <= addr && addr <= address_space_end - 1; | 220 | return address_space_start <= addr && addr <= address_space_end - 1; |
| 223 | } | 221 | } |
| @@ -225,6 +223,8 @@ private: | |||
| 225 | return address_space_start <= addr && addr < addr + size && | 223 | return address_space_start <= addr && addr < addr + size && |
| 226 | addr + size - 1 <= address_space_end - 1; | 224 | addr + size - 1 <= address_space_end - 1; |
| 227 | } | 225 | } |
| 226 | |||
| 227 | private: | ||
| 228 | constexpr bool IsKernel() const { | 228 | constexpr bool IsKernel() const { |
| 229 | return is_kernel; | 229 | return is_kernel; |
| 230 | } | 230 | } |
diff --git a/src/core/hle/kernel/k_transfer_memory.cpp b/src/core/hle/kernel/k_transfer_memory.cpp new file mode 100644 index 000000000..09c067f95 --- /dev/null +++ b/src/core/hle/kernel/k_transfer_memory.cpp | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 6 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 7 | #include "core/hle/kernel/kernel.h" | ||
| 8 | #include "core/hle/kernel/process.h" | ||
| 9 | |||
| 10 | namespace Kernel { | ||
| 11 | |||
| 12 | KTransferMemory::KTransferMemory(KernelCore& kernel) | ||
| 13 | : KAutoObjectWithSlabHeapAndContainer{kernel} {} | ||
| 14 | |||
| 15 | KTransferMemory::~KTransferMemory() = default; | ||
| 16 | |||
| 17 | ResultCode KTransferMemory::Initialize(VAddr address_, std::size_t size_, | ||
| 18 | Svc::MemoryPermission owner_perm_) { | ||
| 19 | // Set members. | ||
| 20 | owner = kernel.CurrentProcess(); | ||
| 21 | |||
| 22 | // TODO(bunnei): Lock for transfer memory | ||
| 23 | |||
| 24 | // Set remaining tracking members. | ||
| 25 | owner->Open(); | ||
| 26 | owner_perm = owner_perm_; | ||
| 27 | address = address_; | ||
| 28 | size = size_; | ||
| 29 | is_initialized = true; | ||
| 30 | |||
| 31 | return RESULT_SUCCESS; | ||
| 32 | } | ||
| 33 | |||
| 34 | void KTransferMemory::Finalize() { | ||
| 35 | // Perform inherited finalization. | ||
| 36 | KAutoObjectWithSlabHeapAndContainer<KTransferMemory, KAutoObjectWithList>::Finalize(); | ||
| 37 | } | ||
| 38 | |||
| 39 | void KTransferMemory::PostDestroy(uintptr_t arg) { | ||
| 40 | Process* owner = reinterpret_cast<Process*>(arg); | ||
| 41 | owner->GetResourceLimit()->Release(LimitableResource::TransferMemory, 1); | ||
| 42 | owner->Close(); | ||
| 43 | } | ||
| 44 | |||
| 45 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h new file mode 100644 index 000000000..f43725c7f --- /dev/null +++ b/src/core/hle/kernel/k_transfer_memory.h | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | |||
| 9 | #include "core/hle/kernel/slab_helpers.h" | ||
| 10 | #include "core/hle/kernel/svc_types.h" | ||
| 11 | #include "core/hle/result.h" | ||
| 12 | |||
| 13 | union ResultCode; | ||
| 14 | |||
| 15 | namespace Core::Memory { | ||
| 16 | class Memory; | ||
| 17 | } | ||
| 18 | |||
| 19 | namespace Kernel { | ||
| 20 | |||
| 21 | class KernelCore; | ||
| 22 | class Process; | ||
| 23 | |||
| 24 | class KTransferMemory final | ||
| 25 | : public KAutoObjectWithSlabHeapAndContainer<KTransferMemory, KAutoObjectWithList> { | ||
| 26 | KERNEL_AUTOOBJECT_TRAITS(KTransferMemory, KAutoObject); | ||
| 27 | |||
| 28 | public: | ||
| 29 | explicit KTransferMemory(KernelCore& kernel); | ||
| 30 | ~KTransferMemory() override; | ||
| 31 | |||
| 32 | static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; | ||
| 33 | |||
| 34 | ResultCode Initialize(VAddr address_, std::size_t size_, Svc::MemoryPermission owner_perm_); | ||
| 35 | |||
| 36 | virtual void Finalize() override; | ||
| 37 | |||
| 38 | virtual bool IsInitialized() const override { | ||
| 39 | return is_initialized; | ||
| 40 | } | ||
| 41 | |||
| 42 | virtual uintptr_t GetPostDestroyArgument() const override { | ||
| 43 | return reinterpret_cast<uintptr_t>(owner); | ||
| 44 | } | ||
| 45 | |||
| 46 | static void PostDestroy(uintptr_t arg); | ||
| 47 | |||
| 48 | Process* GetOwner() const { | ||
| 49 | return owner; | ||
| 50 | } | ||
| 51 | |||
| 52 | VAddr GetSourceAddress() const { | ||
| 53 | return address; | ||
| 54 | } | ||
| 55 | |||
| 56 | size_t GetSize() const { | ||
| 57 | return is_initialized ? size * PageSize : 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | // DEPRECATED | ||
| 61 | |||
| 62 | std::string GetTypeName() const override { | ||
| 63 | return "TransferMemory"; | ||
| 64 | } | ||
| 65 | |||
| 66 | std::string GetName() const override { | ||
| 67 | return GetTypeName(); | ||
| 68 | } | ||
| 69 | |||
| 70 | HandleType GetHandleType() const override { | ||
| 71 | return HANDLE_TYPE; | ||
| 72 | } | ||
| 73 | |||
| 74 | private: | ||
| 75 | Process* owner{}; | ||
| 76 | VAddr address{}; | ||
| 77 | Svc::MemoryPermission owner_perm{}; | ||
| 78 | size_t size{}; | ||
| 79 | bool is_initialized{}; | ||
| 80 | }; | ||
| 81 | |||
| 82 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index ecced1034..f07f0276e 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -42,6 +42,7 @@ class KScheduler; | |||
| 42 | class KSession; | 42 | class KSession; |
| 43 | class KSharedMemory; | 43 | class KSharedMemory; |
| 44 | class KThread; | 44 | class KThread; |
| 45 | class KTransferMemory; | ||
| 45 | class KWritableEvent; | 46 | class KWritableEvent; |
| 46 | class PhysicalCore; | 47 | class PhysicalCore; |
| 47 | class Process; | 48 | class Process; |
| @@ -278,6 +279,8 @@ public: | |||
| 278 | return slab_heap_container->client_session; | 279 | return slab_heap_container->client_session; |
| 279 | } else if constexpr (std::is_same_v<T, KSession>) { | 280 | } else if constexpr (std::is_same_v<T, KSession>) { |
| 280 | return slab_heap_container->session; | 281 | return slab_heap_container->session; |
| 282 | } else if constexpr (std::is_same_v<T, KTransferMemory>) { | ||
| 283 | return slab_heap_container->transfer_memory; | ||
| 281 | } | 284 | } |
| 282 | } | 285 | } |
| 283 | 286 | ||
| @@ -320,6 +323,7 @@ private: | |||
| 320 | KSlabHeap<KWritableEvent> writeable_event; | 323 | KSlabHeap<KWritableEvent> writeable_event; |
| 321 | KSlabHeap<KClientSession> client_session; | 324 | KSlabHeap<KClientSession> client_session; |
| 322 | KSlabHeap<KSession> session; | 325 | KSlabHeap<KSession> session; |
| 326 | KSlabHeap<KTransferMemory> transfer_memory; | ||
| 323 | }; | 327 | }; |
| 324 | 328 | ||
| 325 | std::unique_ptr<SlabHeapContainer> slab_heap_container; | 329 | std::unique_ptr<SlabHeapContainer> slab_heap_container; |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 28c45e8a3..0b7eb0740 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include "core/hle/kernel/k_shared_memory.h" | 38 | #include "core/hle/kernel/k_shared_memory.h" |
| 39 | #include "core/hle/kernel/k_synchronization_object.h" | 39 | #include "core/hle/kernel/k_synchronization_object.h" |
| 40 | #include "core/hle/kernel/k_thread.h" | 40 | #include "core/hle/kernel/k_thread.h" |
| 41 | #include "core/hle/kernel/k_transfer_memory.h" | ||
| 41 | #include "core/hle/kernel/k_writable_event.h" | 42 | #include "core/hle/kernel/k_writable_event.h" |
| 42 | #include "core/hle/kernel/kernel.h" | 43 | #include "core/hle/kernel/kernel.h" |
| 43 | #include "core/hle/kernel/physical_core.h" | 44 | #include "core/hle/kernel/physical_core.h" |
| @@ -47,7 +48,6 @@ | |||
| 47 | #include "core/hle/kernel/svc_types.h" | 48 | #include "core/hle/kernel/svc_types.h" |
| 48 | #include "core/hle/kernel/svc_wrap.h" | 49 | #include "core/hle/kernel/svc_wrap.h" |
| 49 | #include "core/hle/kernel/time_manager.h" | 50 | #include "core/hle/kernel/time_manager.h" |
| 50 | #include "core/hle/kernel/transfer_memory.h" | ||
| 51 | #include "core/hle/lock.h" | 51 | #include "core/hle/lock.h" |
| 52 | #include "core/hle/result.h" | 52 | #include "core/hle/result.h" |
| 53 | #include "core/hle/service/service.h" | 53 | #include "core/hle/service/service.h" |
| @@ -1868,65 +1868,68 @@ static ResultCode ResetSignal32(Core::System& system, Handle handle) { | |||
| 1868 | return ResetSignal(system, handle); | 1868 | return ResetSignal(system, handle); |
| 1869 | } | 1869 | } |
| 1870 | 1870 | ||
| 1871 | /// Creates a TransferMemory object | 1871 | static constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { |
| 1872 | static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size, | 1872 | switch (perm) { |
| 1873 | u32 permissions) { | 1873 | case MemoryPermission::None: |
| 1874 | std::lock_guard lock{HLE::g_hle_lock}; | 1874 | case MemoryPermission::Read: |
| 1875 | LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size, | 1875 | case MemoryPermission::ReadWrite: |
| 1876 | permissions); | 1876 | return true; |
| 1877 | 1877 | default: | |
| 1878 | if (!Common::Is4KBAligned(addr)) { | 1878 | return false; |
| 1879 | LOG_ERROR(Kernel_SVC, "Address ({:016X}) is not page aligned!", addr); | ||
| 1880 | return ResultInvalidAddress; | ||
| 1881 | } | 1879 | } |
| 1880 | } | ||
| 1882 | 1881 | ||
| 1883 | if (!Common::Is4KBAligned(size) || size == 0) { | 1882 | /// Creates a TransferMemory object |
| 1884 | LOG_ERROR(Kernel_SVC, "Size ({:016X}) is not page aligned or equal to zero!", size); | 1883 | static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, |
| 1885 | return ResultInvalidAddress; | 1884 | MemoryPermission map_perm) { |
| 1886 | } | 1885 | auto& kernel = system.Kernel(); |
| 1887 | 1886 | ||
| 1888 | if (!IsValidAddressRange(addr, size)) { | 1887 | // Validate the size. |
| 1889 | LOG_ERROR(Kernel_SVC, "Address and size cause overflow! (address={:016X}, size={:016X})", | 1888 | R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); |
| 1890 | addr, size); | 1889 | R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); |
| 1891 | return ResultInvalidCurrentMemory; | 1890 | R_UNLESS(size > 0, ResultInvalidSize); |
| 1892 | } | 1891 | R_UNLESS((address < address + size), ResultInvalidCurrentMemory); |
| 1893 | 1892 | ||
| 1894 | const auto perms{static_cast<MemoryPermission>(permissions)}; | 1893 | // Validate the permissions. |
| 1895 | if (perms > MemoryPermission::ReadWrite || perms == MemoryPermission::Write) { | 1894 | R_UNLESS(IsValidTransferMemoryPermission(map_perm), ResultInvalidNewMemoryPermission); |
| 1896 | LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", | 1895 | |
| 1897 | permissions); | 1896 | // Get the current process and handle table. |
| 1898 | return ResultInvalidNewMemoryPermission; | 1897 | auto& process = *kernel.CurrentProcess(); |
| 1899 | } | 1898 | auto& handle_table = process.GetHandleTable(); |
| 1900 | 1899 | ||
| 1901 | auto& kernel = system.Kernel(); | ||
| 1902 | // Reserve a new transfer memory from the process resource limit. | 1900 | // Reserve a new transfer memory from the process resource limit. |
| 1903 | KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(), | 1901 | KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(), |
| 1904 | LimitableResource::TransferMemory); | 1902 | LimitableResource::TransferMemory); |
| 1905 | if (!trmem_reservation.Succeeded()) { | 1903 | R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached); |
| 1906 | LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory"); | ||
| 1907 | return ResultLimitReached; | ||
| 1908 | } | ||
| 1909 | auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, | ||
| 1910 | static_cast<KMemoryPermission>(perms)); | ||
| 1911 | 1904 | ||
| 1912 | if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { | 1905 | // Create the transfer memory. |
| 1913 | return reserve_result; | 1906 | KTransferMemory* trmem = KTransferMemory::Create(kernel); |
| 1914 | } | 1907 | R_UNLESS(trmem != nullptr, ResultOutOfResource); |
| 1915 | 1908 | ||
| 1916 | auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); | 1909 | // Ensure the only reference is in the handle table when we're done. |
| 1917 | const auto result{handle_table.Create(transfer_mem_handle.get())}; | 1910 | SCOPE_EXIT({ trmem->Close(); }); |
| 1918 | if (result.Failed()) { | 1911 | |
| 1919 | return result.Code(); | 1912 | // Ensure that the region is in range. |
| 1920 | } | 1913 | R_UNLESS(process.PageTable().Contains(address, size), ResultInvalidCurrentMemory); |
| 1914 | |||
| 1915 | // Initialize the transfer memory. | ||
| 1916 | R_TRY(trmem->Initialize(address, size, map_perm)); | ||
| 1917 | |||
| 1918 | // Commit the reservation. | ||
| 1921 | trmem_reservation.Commit(); | 1919 | trmem_reservation.Commit(); |
| 1922 | 1920 | ||
| 1923 | *handle = *result; | 1921 | // Register the transfer memory. |
| 1922 | KTransferMemory::Register(kernel, trmem); | ||
| 1923 | |||
| 1924 | // Add the transfer memory to the handle table. | ||
| 1925 | R_TRY(handle_table.Add(out, trmem)); | ||
| 1926 | |||
| 1924 | return RESULT_SUCCESS; | 1927 | return RESULT_SUCCESS; |
| 1925 | } | 1928 | } |
| 1926 | 1929 | ||
| 1927 | static ResultCode CreateTransferMemory32(Core::System& system, Handle* handle, u32 addr, u32 size, | 1930 | static ResultCode CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, |
| 1928 | u32 permissions) { | 1931 | MemoryPermission map_perm) { |
| 1929 | return CreateTransferMemory(system, handle, addr, size, permissions); | 1932 | return CreateTransferMemory(system, out, address, size, map_perm); |
| 1930 | } | 1933 | } |
| 1931 | 1934 | ||
| 1932 | static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, | 1935 | static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, |
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 96afd544b..819eadfbb 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h | |||
| @@ -273,11 +273,12 @@ void SvcWrap64(Core::System& system) { | |||
| 273 | FuncReturn(system, retval); | 273 | FuncReturn(system, retval); |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | template <ResultCode func(Core::System&, u32*, u64, u64, u32)> | 276 | // Used by CreateTransferMemory |
| 277 | template <ResultCode func(Core::System&, Handle*, u64, u64, Svc::MemoryPermission)> | ||
| 277 | void SvcWrap64(Core::System& system) { | 278 | void SvcWrap64(Core::System& system) { |
| 278 | u32 param_1 = 0; | 279 | u32 param_1 = 0; |
| 279 | const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), | 280 | const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), |
| 280 | static_cast<u32>(Param(system, 3))) | 281 | static_cast<Svc::MemoryPermission>(Param(system, 3))) |
| 281 | .raw; | 282 | .raw; |
| 282 | 283 | ||
| 283 | system.CurrentArmInterface().SetReg(1, param_1); | 284 | system.CurrentArmInterface().SetReg(1, param_1); |
| @@ -586,11 +587,12 @@ void SvcWrap32(Core::System& system) { | |||
| 586 | } | 587 | } |
| 587 | 588 | ||
| 588 | // Used by CreateTransferMemory32 | 589 | // Used by CreateTransferMemory32 |
| 589 | template <ResultCode func(Core::System&, Handle*, u32, u32, u32)> | 590 | template <ResultCode func(Core::System&, Handle*, u32, u32, Svc::MemoryPermission)> |
| 590 | void SvcWrap32(Core::System& system) { | 591 | void SvcWrap32(Core::System& system) { |
| 591 | Handle handle = 0; | 592 | Handle handle = 0; |
| 592 | const u32 retval = | 593 | const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2), |
| 593 | func(system, &handle, Param32(system, 1), Param32(system, 2), Param32(system, 3)).raw; | 594 | static_cast<Svc::MemoryPermission>(Param32(system, 3))) |
| 595 | .raw; | ||
| 594 | system.CurrentArmInterface().SetReg(1, handle); | 596 | system.CurrentArmInterface().SetReg(1, handle); |
| 595 | FuncReturn(system, retval); | 597 | FuncReturn(system, retval); |
| 596 | } | 598 | } |