summaryrefslogtreecommitdiff
path: root/src/core/hle/svc.cpp
diff options
context:
space:
mode:
authorGravatar Subv2016-04-17 21:07:52 -0500
committerGravatar Subv2016-05-12 20:00:32 -0500
commit1bd0cf542ff8db1cda572c4d92462643296af121 (patch)
tree8004faa76770c076e2d84d51a64c6419f796a477 /src/core/hle/svc.cpp
parentKernel/SVC: Fixed the register order for svcCreateMemoryBlock. (diff)
downloadyuzu-1bd0cf542ff8db1cda572c4d92462643296af121.tar.gz
yuzu-1bd0cf542ff8db1cda572c4d92462643296af121.tar.xz
yuzu-1bd0cf542ff8db1cda572c4d92462643296af121.zip
Kernel/SharedMemory: Properly implemented shared memory support.
Applications can request the kernel to allocate a piece of the linear heap for them when creating a shared memory object. Shared memory areas are now properly mapped into the target processes when calling svcMapMemoryBlock. Removed the APT Shared Font hack as it is no longer needed.
Diffstat (limited to 'src/core/hle/svc.cpp')
-rw-r--r--src/core/hle/svc.cpp47
1 files changed, 35 insertions, 12 deletions
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 60c8747f3..701dffef3 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -160,8 +160,6 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
160 LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", 160 LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d",
161 handle, addr, permissions, other_permissions); 161 handle, addr, permissions, other_permissions);
162 162
163 // TODO(Subv): The same process that created a SharedMemory object can not map it in its own address space
164
165 SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); 163 SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
166 if (shared_memory == nullptr) 164 if (shared_memory == nullptr)
167 return ERR_INVALID_HANDLE; 165 return ERR_INVALID_HANDLE;
@@ -176,7 +174,7 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
176 case MemoryPermission::WriteExecute: 174 case MemoryPermission::WriteExecute:
177 case MemoryPermission::ReadWriteExecute: 175 case MemoryPermission::ReadWriteExecute:
178 case MemoryPermission::DontCare: 176 case MemoryPermission::DontCare:
179 return shared_memory->Map(addr, permissions_type, 177 return shared_memory->Map(Kernel::g_current_process.get(), addr, permissions_type,
180 static_cast<MemoryPermission>(other_permissions)); 178 static_cast<MemoryPermission>(other_permissions));
181 default: 179 default:
182 LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); 180 LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
@@ -196,7 +194,7 @@ static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) {
196 if (shared_memory == nullptr) 194 if (shared_memory == nullptr)
197 return ERR_INVALID_HANDLE; 195 return ERR_INVALID_HANDLE;
198 196
199 return shared_memory->Unmap(addr); 197 return shared_memory->Unmap(Kernel::g_current_process.get(), addr);
200} 198}
201 199
202/// Connect to an OS service given the port name, returns the handle to the port to out 200/// Connect to an OS service given the port name, returns the handle to the port to out
@@ -790,18 +788,43 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
790 if (size % Memory::PAGE_SIZE != 0) 788 if (size % Memory::PAGE_SIZE != 0)
791 return ResultCode(ErrorDescription::MisalignedSize, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 789 return ResultCode(ErrorDescription::MisalignedSize, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage);
792 790
793 // TODO(Subv): Return E0A01BF5 if the address is not in the application's heap 791 SharedPtr<SharedMemory> shared_memory = nullptr;
794
795 // TODO(Subv): Implement this function properly
796 792
797 using Kernel::MemoryPermission; 793 using Kernel::MemoryPermission;
798 SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size, 794 auto VerifyPermissions = [](MemoryPermission permission) {
799 (MemoryPermission)my_permission, (MemoryPermission)other_permission); 795 // SharedMemory blocks can not be created with Execute permissions
800 // Map the SharedMemory to the specified address 796 switch (permission) {
801 shared_memory->base_address = addr; 797 case MemoryPermission::None:
798 case MemoryPermission::Read:
799 case MemoryPermission::Write:
800 case MemoryPermission::ReadWrite:
801 return true;
802 default:
803 return false;
804 }
805 };
806
807 if (!VerifyPermissions(static_cast<MemoryPermission>(my_permission)) ||
808 !VerifyPermissions(static_cast<MemoryPermission>(other_permission)))
809 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS,
810 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
811
812 if (addr < Memory::PROCESS_IMAGE_VADDR || addr + size > Memory::SHARED_MEMORY_VADDR_END) {
813 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage);
814 }
815
816 // When trying to create a memory block with address = 0,
817 // if the process has the Shared Device Memory flag in the exheader,
818 // then we have to allocate from the same region as the caller process instead of the BASE region.
819 Kernel::MemoryRegion region = Kernel::MemoryRegion::BASE;
820 if (addr == 0 && Kernel::g_current_process->flags.shared_device_mem)
821 region = Kernel::g_current_process->flags.memory_region;
822
823 shared_memory = SharedMemory::Create(Kernel::g_current_process, size,
824 static_cast<MemoryPermission>(my_permission), static_cast<MemoryPermission>(other_permission), addr, region);
802 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); 825 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory)));
803 826
804 LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr); 827 LOG_WARNING(Kernel_SVC, "called addr=0x%08X", addr);
805 return RESULT_SUCCESS; 828 return RESULT_SUCCESS;
806} 829}
807 830