mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #28 from bunnei/shared-memory
Shared memory - adds preliminary support for shared memory kernel objects and correct block mapping.
This commit is contained in:
		
						commit
						6084084a5d
					
				
					 9 changed files with 226 additions and 78 deletions
				
			
		|  | @ -38,6 +38,7 @@ set(SRCS    core.cpp | ||||||
|             hle/kernel/event.cpp |             hle/kernel/event.cpp | ||||||
|             hle/kernel/kernel.cpp |             hle/kernel/kernel.cpp | ||||||
|             hle/kernel/mutex.cpp |             hle/kernel/mutex.cpp | ||||||
|  |             hle/kernel/shared_memory.cpp | ||||||
|             hle/kernel/thread.cpp |             hle/kernel/thread.cpp | ||||||
|             hle/service/apt.cpp |             hle/service/apt.cpp | ||||||
|             hle/service/fs.cpp |             hle/service/fs.cpp | ||||||
|  | @ -85,6 +86,7 @@ set(HEADERS core.h | ||||||
|             hle/kernel/archive.h |             hle/kernel/archive.h | ||||||
|             hle/kernel/kernel.h |             hle/kernel/kernel.h | ||||||
|             hle/kernel/mutex.h |             hle/kernel/mutex.h | ||||||
|  |             hle/kernel/shared_memory.h | ||||||
|             hle/kernel/thread.h |             hle/kernel/thread.h | ||||||
|             hle/function_wrappers.h |             hle/function_wrappers.h | ||||||
|             hle/service/apt.h |             hle/service/apt.h | ||||||
|  |  | ||||||
|  | @ -170,6 +170,7 @@ | ||||||
|     <ClCompile Include="hle\kernel\event.cpp" /> |     <ClCompile Include="hle\kernel\event.cpp" /> | ||||||
|     <ClCompile Include="hle\kernel\kernel.cpp" /> |     <ClCompile Include="hle\kernel\kernel.cpp" /> | ||||||
|     <ClCompile Include="hle\kernel\mutex.cpp" /> |     <ClCompile Include="hle\kernel\mutex.cpp" /> | ||||||
|  |     <ClCompile Include="hle\kernel\shared_memory.cpp" /> | ||||||
|     <ClCompile Include="hle\kernel\thread.cpp" /> |     <ClCompile Include="hle\kernel\thread.cpp" /> | ||||||
|     <ClCompile Include="hle\service\apt.cpp" /> |     <ClCompile Include="hle\service\apt.cpp" /> | ||||||
|     <ClCompile Include="hle\service\fs.cpp" /> |     <ClCompile Include="hle\service\fs.cpp" /> | ||||||
|  | @ -222,6 +223,7 @@ | ||||||
|     <ClInclude Include="hle\kernel\event.h" /> |     <ClInclude Include="hle\kernel\event.h" /> | ||||||
|     <ClInclude Include="hle\kernel\kernel.h" /> |     <ClInclude Include="hle\kernel\kernel.h" /> | ||||||
|     <ClInclude Include="hle\kernel\mutex.h" /> |     <ClInclude Include="hle\kernel\mutex.h" /> | ||||||
|  |     <ClInclude Include="hle\kernel\shared_memory.h" /> | ||||||
|     <ClInclude Include="hle\kernel\thread.h" /> |     <ClInclude Include="hle\kernel\thread.h" /> | ||||||
|     <ClInclude Include="hle\service\apt.h" /> |     <ClInclude Include="hle\service\apt.h" /> | ||||||
|     <ClInclude Include="hle\service\fs.h" /> |     <ClInclude Include="hle\service\fs.h" /> | ||||||
|  |  | ||||||
|  | @ -179,6 +179,9 @@ | ||||||
|     <ClCompile Include="file_sys\archive_romfs.cpp"> |     <ClCompile Include="file_sys\archive_romfs.cpp"> | ||||||
|       <Filter>file_sys</Filter> |       <Filter>file_sys</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="hle\kernel\shared_memory.cpp"> | ||||||
|  |       <Filter>hle\kernel</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="arm\disassembler\arm_disasm.h"> |     <ClInclude Include="arm\disassembler\arm_disasm.h"> | ||||||
|  | @ -320,6 +323,9 @@ | ||||||
|     <ClInclude Include="file_sys\archive_romfs.h"> |     <ClInclude Include="file_sys\archive_romfs.h"> | ||||||
|       <Filter>file_sys</Filter> |       <Filter>file_sys</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="hle\kernel\shared_memory.h"> | ||||||
|  |       <Filter>hle\kernel</Filter> | ||||||
|  |     </ClInclude> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <Text Include="CMakeLists.txt" /> |     <Text Include="CMakeLists.txt" /> | ||||||
|  |  | ||||||
							
								
								
									
										105
									
								
								src/core/hle/kernel/shared_memory.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/core/hle/kernel/shared_memory.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,105 @@ | ||||||
|  | // Copyright 2014 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2
 | ||||||
|  | // Refer to the license.txt file included.  
 | ||||||
|  | 
 | ||||||
|  | #include "common/common.h" | ||||||
|  | 
 | ||||||
|  | #include "core/mem_map.h" | ||||||
|  | #include "core/hle/kernel/shared_memory.h" | ||||||
|  | 
 | ||||||
|  | namespace Kernel { | ||||||
|  | 
 | ||||||
|  | class SharedMemory : public Object { | ||||||
|  | public: | ||||||
|  |     const char* GetTypeName() const { return "SharedMemory"; } | ||||||
|  | 
 | ||||||
|  |     static Kernel::HandleType GetStaticHandleType() {  return Kernel::HandleType::SharedMemory; } | ||||||
|  |     Kernel::HandleType GetHandleType() const { return Kernel::HandleType::SharedMemory; } | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * Wait for kernel object to synchronize | ||||||
|  |      * @param wait Boolean wait set if current thread should wait as a result of sync operation | ||||||
|  |      * @return Result of operation, 0 on success, otherwise error code | ||||||
|  |      */ | ||||||
|  |     Result WaitSynchronization(bool* wait) { | ||||||
|  |         // TODO(bunnei): ImplementMe
 | ||||||
|  |         ERROR_LOG(OSHLE, "(UNIMPLEMENTED)"); | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     u32 base_address;                   ///< Address of shared memory block in RAM
 | ||||||
|  |     MemoryPermission permissions;       ///< Permissions of shared memory block (SVC field)
 | ||||||
|  |     MemoryPermission other_permissions; ///< Other permissions of shared memory block (SVC field)
 | ||||||
|  |     std::string name;                   ///< Name of shared memory object (optional)
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Creates a shared memory object | ||||||
|  |  * @param handle Handle of newly created shared memory object | ||||||
|  |  * @param name Name of shared memory object | ||||||
|  |  * @return Pointer to newly created shared memory object | ||||||
|  |  */ | ||||||
|  | SharedMemory* CreateSharedMemory(Handle& handle, const std::string& name) { | ||||||
|  |     SharedMemory* shared_memory = new SharedMemory; | ||||||
|  |     handle = Kernel::g_object_pool.Create(shared_memory); | ||||||
|  |     shared_memory->name = name; | ||||||
|  |     return shared_memory; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Creates a shared memory object | ||||||
|  |  * @param name Optional name of shared memory object | ||||||
|  |  * @return Handle of newly created shared memory object | ||||||
|  |  */ | ||||||
|  | Handle CreateSharedMemory(const std::string& name) { | ||||||
|  |     Handle handle; | ||||||
|  |     CreateSharedMemory(handle, name); | ||||||
|  |     return handle; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Maps a shared memory block to an address in system memory | ||||||
|  |  * @param handle Shared memory block handle | ||||||
|  |  * @param address Address in system memory to map shared memory block to | ||||||
|  |  * @param permissions Memory block map permissions (specified by SVC field) | ||||||
|  |  * @param other_permissions Memory block map other permissions (specified by SVC field) | ||||||
|  |  * @return Result of operation, 0 on success, otherwise error code | ||||||
|  |  */ | ||||||
|  | Result MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions,  | ||||||
|  |     MemoryPermission other_permissions) { | ||||||
|  | 
 | ||||||
|  |     if (address < Memory::SHARED_MEMORY_VADDR || address >= Memory::SHARED_MEMORY_VADDR_END) { | ||||||
|  |         ERROR_LOG(KERNEL, "cannot map handle=0x%08X, address=0x%08X outside of shared mem bounds!", | ||||||
|  |             handle); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |     SharedMemory* shared_memory = Kernel::g_object_pool.GetFast<SharedMemory>(handle); | ||||||
|  |     _assert_msg_(KERNEL, (shared_memory != nullptr), "handle 0x%08X is not valid!", handle); | ||||||
|  | 
 | ||||||
|  |     shared_memory->base_address = address; | ||||||
|  |     shared_memory->permissions = permissions; | ||||||
|  |     shared_memory->other_permissions = other_permissions; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Gets a pointer to the shared memory block | ||||||
|  |  * @param handle Shared memory block handle | ||||||
|  |  * @param offset Offset from the start of the shared memory block to get pointer | ||||||
|  |  * @return Pointer to the shared memory block from the specified offset | ||||||
|  |  */ | ||||||
|  | u8* GetSharedMemoryPointer(Handle handle, u32 offset) { | ||||||
|  |     SharedMemory* shared_memory = Kernel::g_object_pool.GetFast<SharedMemory>(handle); | ||||||
|  |     _assert_msg_(KERNEL, (shared_memory != nullptr), "handle 0x%08X is not valid!", handle); | ||||||
|  | 
 | ||||||
|  |     if (0 != shared_memory->base_address) | ||||||
|  |         return Memory::GetPointer(shared_memory->base_address + offset); | ||||||
|  | 
 | ||||||
|  |     ERROR_LOG(KERNEL, "memory block handle=0x%08X not mapped!", handle); | ||||||
|  |     return nullptr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace
 | ||||||
							
								
								
									
										48
									
								
								src/core/hle/kernel/shared_memory.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/core/hle/kernel/shared_memory.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | ||||||
|  | // Copyright 2014 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2
 | ||||||
|  | // Refer to the license.txt file included.  
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "common/common_types.h" | ||||||
|  | 
 | ||||||
|  | #include "core/hle/kernel/kernel.h" | ||||||
|  | 
 | ||||||
|  | namespace Kernel { | ||||||
|  | 
 | ||||||
|  | /// Permissions for mapped shared memory blocks
 | ||||||
|  | enum class MemoryPermission : u32 { | ||||||
|  |     None        = 0, | ||||||
|  |     Read        = (1u <<  0), | ||||||
|  |     Write       = (1u <<  1), | ||||||
|  |     ReadWrite   = (Read | Write), | ||||||
|  |     DontCare    = (1u << 28) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Creates a shared memory object | ||||||
|  |  * @param name Optional name of shared memory object | ||||||
|  |  * @return Handle of newly created shared memory object | ||||||
|  |  */ | ||||||
|  | Handle CreateSharedMemory(const std::string& name="Unknown"); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Maps a shared memory block to an address in system memory | ||||||
|  |  * @param handle Shared memory block handle | ||||||
|  |  * @param address Address in system memory to map shared memory block to | ||||||
|  |  * @param permissions Memory block map permissions (specified by SVC field) | ||||||
|  |  * @param other_permissions Memory block map other permissions (specified by SVC field) | ||||||
|  |  * @return Result of operation, 0 on success, otherwise error code | ||||||
|  |  */ | ||||||
|  | Result MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions,  | ||||||
|  |     MemoryPermission other_permissions); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Gets a pointer to the shared memory block | ||||||
|  |  * @param handle Shared memory block handle | ||||||
|  |  * @param offset Offset from the start of the shared memory block to get pointer | ||||||
|  |  * @return Pointer to the shared memory block from the specified offset | ||||||
|  |  */ | ||||||
|  | u8* GetSharedMemoryPointer(Handle handle, u32 offset); | ||||||
|  | 
 | ||||||
|  | } // namespace
 | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| #include "core/mem_map.h" | #include "core/mem_map.h" | ||||||
| #include "core/hle/hle.h" | #include "core/hle/hle.h" | ||||||
| #include "core/hle/kernel/event.h" | #include "core/hle/kernel/event.h" | ||||||
|  | #include "core/hle/kernel/shared_memory.h" | ||||||
| #include "core/hle/service/gsp.h" | #include "core/hle/service/gsp.h" | ||||||
| 
 | 
 | ||||||
| #include "core/hw/gpu.h" | #include "core/hw/gpu.h" | ||||||
|  | @ -36,14 +37,24 @@ union GX_CmdBufferHeader { | ||||||
|     BitField<8,8,u32>   number_commands; |     BitField<8,8,u32>   number_commands; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /// Gets the address of the start (header) of a command buffer in GSP shared memory
 | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| static inline u32 GX_GetCmdBufferAddress(u32 thread_id) { | // Namespace GSP_GPU
 | ||||||
|     return (0x10002000 + 0x800 + (thread_id * 0x200)); | 
 | ||||||
| } | namespace GSP_GPU { | ||||||
|  | 
 | ||||||
|  | Handle g_event = 0; | ||||||
|  | Handle g_shared_memory = 0; | ||||||
|  | 
 | ||||||
|  | u32 g_thread_id = 0; | ||||||
|  | 
 | ||||||
|  | enum { | ||||||
|  |     REG_FRAMEBUFFER_1   = 0x00400468, | ||||||
|  |     REG_FRAMEBUFFER_2   = 0x00400494, | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| /// Gets a pointer to the start (header) of a command buffer in GSP shared memory
 | /// Gets a pointer to the start (header) of a command buffer in GSP shared memory
 | ||||||
| static inline u8* GX_GetCmdBufferPointer(u32 thread_id, u32 offset=0) { | static inline u8* GX_GetCmdBufferPointer(u32 thread_id, u32 offset=0) { | ||||||
|     return Memory::GetPointer(GX_GetCmdBufferAddress(thread_id) + offset); |     return Kernel::GetSharedMemoryPointer(g_shared_memory, 0x800 + (thread_id * 0x200) + offset); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Finishes execution of a GSP command
 | /// Finishes execution of a GSP command
 | ||||||
|  | @ -56,19 +67,6 @@ void GX_FinishCommand(u32 thread_id) { | ||||||
|     // TODO: Increment header->index?
 |     // TODO: Increment header->index?
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 |  | ||||||
| // Namespace GSP_GPU
 |  | ||||||
| 
 |  | ||||||
| namespace GSP_GPU { |  | ||||||
| 
 |  | ||||||
| Handle g_event_handle = 0; |  | ||||||
| u32 g_thread_id = 0; |  | ||||||
| 
 |  | ||||||
| enum { |  | ||||||
|     REG_FRAMEBUFFER_1   = 0x00400468, |  | ||||||
|     REG_FRAMEBUFFER_2   = 0x00400494, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /// Read a GSP GPU hardware register
 | /// Read a GSP GPU hardware register
 | ||||||
| void ReadHWRegs(Service::Interface* self) { | void ReadHWRegs(Service::Interface* self) { | ||||||
|     static const u32 framebuffer_1[] = {GPU::PADDR_VRAM_TOP_LEFT_FRAME1, GPU::PADDR_VRAM_TOP_RIGHT_FRAME1}; |     static const u32 framebuffer_1[] = {GPU::PADDR_VRAM_TOP_LEFT_FRAME1, GPU::PADDR_VRAM_TOP_RIGHT_FRAME1}; | ||||||
|  | @ -103,24 +101,34 @@ void ReadHWRegs(Service::Interface* self) { | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * GSP_GPU::RegisterInterruptRelayQueue service function | ||||||
|  |  *  Inputs: | ||||||
|  |  *      1 : "Flags" field, purpose is unknown | ||||||
|  |  *      3 : Handle to GSP synchronization event | ||||||
|  |  *  Outputs: | ||||||
|  |  *      0 : Result of function, 0 on success, otherwise error code | ||||||
|  |  *      2 : Thread index into GSP command buffer | ||||||
|  |  *      4 : Handle to GSP shared memory | ||||||
|  |  */ | ||||||
| void RegisterInterruptRelayQueue(Service::Interface* self) { | void RegisterInterruptRelayQueue(Service::Interface* self) { | ||||||
|     u32* cmd_buff = Service::GetCommandBuffer(); |     u32* cmd_buff = Service::GetCommandBuffer(); | ||||||
|     u32 flags = cmd_buff[1]; |     u32 flags = cmd_buff[1]; | ||||||
|     u32 event_handle = cmd_buff[3]; |     g_event = cmd_buff[3]; | ||||||
| 
 | 
 | ||||||
|     _assert_msg_(GSP, (event_handle != 0), "called, but event is nullptr!"); |     _assert_msg_(GSP, (g_event != 0), "handle is not valid!"); | ||||||
| 
 | 
 | ||||||
|     g_event_handle = event_handle; |     Kernel::SetEventLocked(g_event, false); | ||||||
| 
 |  | ||||||
|     Kernel::SetEventLocked(event_handle, false); |  | ||||||
| 
 | 
 | ||||||
|     // Hack - This function will permanently set the state of the GSP event such that GPU command 
 |     // Hack - This function will permanently set the state of the GSP event such that GPU command 
 | ||||||
|     // synchronization barriers always passthrough. Correct solution would be to set this after the 
 |     // synchronization barriers always passthrough. Correct solution would be to set this after the 
 | ||||||
|     // GPU as processed all queued up commands, but due to the emulator being single-threaded they
 |     // GPU as processed all queued up commands, but due to the emulator being single-threaded they
 | ||||||
|     // will always be ready.
 |     // will always be ready.
 | ||||||
|     Kernel::SetPermanentLock(event_handle, true); |     Kernel::SetPermanentLock(g_event, true); | ||||||
| 
 | 
 | ||||||
|     cmd_buff[2] = g_thread_id;          // ThreadID
 |     cmd_buff[0] = 0;                // Result - no error
 | ||||||
|  |     cmd_buff[2] = g_thread_id;      // ThreadID
 | ||||||
|  |     cmd_buff[4] = g_shared_memory;  // GSP shared memory
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -208,6 +216,7 @@ const Interface::FunctionInfo FunctionTable[] = { | ||||||
| 
 | 
 | ||||||
| Interface::Interface() { | Interface::Interface() { | ||||||
|     Register(FunctionTable, ARRAY_SIZE(FunctionTable)); |     Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | ||||||
|  |     g_shared_memory = Kernel::CreateSharedMemory("GSPSharedMem"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Interface::~Interface() { | Interface::~Interface() { | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
| #include "core/hle/kernel/event.h" | #include "core/hle/kernel/event.h" | ||||||
| #include "core/hle/kernel/kernel.h" | #include "core/hle/kernel/kernel.h" | ||||||
| #include "core/hle/kernel/mutex.h" | #include "core/hle/kernel/mutex.h" | ||||||
|  | #include "core/hle/kernel/shared_memory.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
| 
 | 
 | ||||||
| #include "core/hle/function_wrappers.h" | #include "core/hle/function_wrappers.h" | ||||||
|  | @ -28,11 +29,6 @@ enum ControlMemoryOperation { | ||||||
|     MEMORY_OPERATION_GSP_HEAP   = 0x00010003, |     MEMORY_OPERATION_GSP_HEAP   = 0x00010003, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| enum MapMemoryPermission { |  | ||||||
|     MEMORY_PERMISSION_UNMAP     = 0x00000000, |  | ||||||
|     MEMORY_PERMISSION_NORMAL    = 0x00000001, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /// Map application or GSP heap memory
 | /// Map application or GSP heap memory
 | ||||||
| Result ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { | Result ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { | ||||||
|     DEBUG_LOG(SVC,"called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=%08X, permissions=0x%08X",  |     DEBUG_LOG(SVC,"called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=%08X, permissions=0x%08X",  | ||||||
|  | @ -58,17 +54,21 @@ Result ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 siz | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Maps a memory block to specified address
 | /// Maps a memory block to specified address
 | ||||||
| Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission) { | Result MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions) { | ||||||
|     DEBUG_LOG(SVC, "called memblock=0x08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d",  |     DEBUG_LOG(SVC, "called memblock=0x08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d",  | ||||||
|         memblock, addr, mypermissions, otherpermission); |         handle, addr, permissions, other_permissions); | ||||||
|     switch (mypermissions) { | 
 | ||||||
|     case MEMORY_PERMISSION_NORMAL: |     Kernel::MemoryPermission permissions_type = static_cast<Kernel::MemoryPermission>(permissions); | ||||||
|     case MEMORY_PERMISSION_NORMAL + 1: |     switch (permissions_type) { | ||||||
|     case MEMORY_PERMISSION_NORMAL + 2: |     case Kernel::MemoryPermission::Read: | ||||||
|         Memory::MapBlock_Shared(memblock, addr, mypermissions); |     case Kernel::MemoryPermission::Write: | ||||||
|  |     case Kernel::MemoryPermission::ReadWrite: | ||||||
|  |     case Kernel::MemoryPermission::DontCare: | ||||||
|  |         Kernel::MapSharedMemory(handle, addr, permissions_type,  | ||||||
|  |             static_cast<Kernel::MemoryPermission>(other_permissions)); | ||||||
|         break; |         break; | ||||||
|     default: |     default: | ||||||
|         ERROR_LOG(OSHLE, "unknown permissions=0x%08X", mypermissions); |         ERROR_LOG(OSHLE, "unknown permissions=0x%08X", permissions); | ||||||
|     } |     } | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -128,6 +128,12 @@ extern u8* g_exefs_code;    ///< ExeFS:/.code is loaded here | ||||||
| void Init(); | void Init(); | ||||||
| void Shutdown(); | void Shutdown(); | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline void Read(T &var, const u32 addr); | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | inline void Write(u32 addr, const T data); | ||||||
|  | 
 | ||||||
| u8 Read8(const u32 addr); | u8 Read8(const u32 addr); | ||||||
| u16 Read16(const u32 addr); | u16 Read16(const u32 addr); | ||||||
| u32 Read32(const u32 addr); | u32 Read32(const u32 addr); | ||||||
|  | @ -143,14 +149,6 @@ void WriteBlock(const u32 addr, const u8* data, const int size); | ||||||
| 
 | 
 | ||||||
| u8* GetPointer(const u32 Address); | u8* GetPointer(const u32 Address); | ||||||
| 
 | 
 | ||||||
| /**
 |  | ||||||
|  * Maps a block of memory in shared memory |  | ||||||
|  * @param handle Handle to map memory block for |  | ||||||
|  * @param addr Address to map memory block to |  | ||||||
|  * @param permissions Memory map permissions |  | ||||||
|  */ |  | ||||||
| u32 MapBlock_Shared(u32 handle, u32 addr,u32 permissions) ; |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * Maps a block of memory on the heap |  * Maps a block of memory on the heap | ||||||
|  * @param size Size of block in bytes |  * @param size Size of block in bytes | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ u32 _VirtualAddress(const u32 addr) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| inline void _Read(T &var, const u32 addr) { | inline void Read(T &var, const u32 addr) { | ||||||
|     // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
 |     // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
 | ||||||
|     // TODO: Make sure this represents the mirrors in a correct way.
 |     // TODO: Make sure this represents the mirrors in a correct way.
 | ||||||
|     // Could just do a base-relative read, too.... TODO
 |     // Could just do a base-relative read, too.... TODO
 | ||||||
|  | @ -91,7 +91,7 @@ inline void _Read(T &var, const u32 addr) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| inline void _Write(u32 addr, const T data) { | inline void Write(u32 addr, const T data) { | ||||||
|     u32 vaddr = _VirtualAddress(addr); |     u32 vaddr = _VirtualAddress(addr); | ||||||
|      |      | ||||||
|     // Kernel memory command buffer
 |     // Kernel memory command buffer
 | ||||||
|  | @ -177,28 +177,6 @@ u8 *GetPointer(const u32 addr) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 |  | ||||||
|  * Maps a block of memory in shared memory |  | ||||||
|  * @param handle Handle to map memory block for |  | ||||||
|  * @param addr Address to map memory block to |  | ||||||
|  * @param permissions Memory map permissions |  | ||||||
|  */ |  | ||||||
| u32 MapBlock_Shared(u32 handle, u32 addr,u32 permissions) { |  | ||||||
|     MemoryBlock block; |  | ||||||
|      |  | ||||||
|     block.handle        = handle; |  | ||||||
|     block.base_address  = addr; |  | ||||||
|     block.permissions   = permissions; |  | ||||||
|      |  | ||||||
|     if (g_shared_map.size() > 0) { |  | ||||||
|         const MemoryBlock last_block = g_shared_map.rbegin()->second; |  | ||||||
|         block.address = last_block.address + last_block.size; |  | ||||||
|     } |  | ||||||
|     g_shared_map[block.GetVirtualAddress()] = block; |  | ||||||
| 
 |  | ||||||
|     return block.GetVirtualAddress(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * Maps a block of memory on the heap |  * Maps a block of memory on the heap | ||||||
|  * @param size Size of block in bytes |  * @param size Size of block in bytes | ||||||
|  | @ -247,25 +225,25 @@ u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions) { | ||||||
| 
 | 
 | ||||||
| u8 Read8(const u32 addr) { | u8 Read8(const u32 addr) { | ||||||
|     u8 _var = 0; |     u8 _var = 0; | ||||||
|     _Read<u8>(_var, addr); |     Read<u8>(_var, addr); | ||||||
|     return (u8)_var; |     return (u8)_var; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u16 Read16(const u32 addr) { | u16 Read16(const u32 addr) { | ||||||
|     u16_le _var = 0; |     u16_le _var = 0; | ||||||
|     _Read<u16_le>(_var, addr); |     Read<u16_le>(_var, addr); | ||||||
|     return (u16)_var; |     return (u16)_var; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u32 Read32(const u32 addr) { | u32 Read32(const u32 addr) { | ||||||
|     u32_le _var = 0; |     u32_le _var = 0; | ||||||
|     _Read<u32_le>(_var, addr); |     Read<u32_le>(_var, addr); | ||||||
|     return _var; |     return _var; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u64 Read64(const u32 addr) { | u64 Read64(const u32 addr) { | ||||||
|     u64_le _var = 0; |     u64_le _var = 0; | ||||||
|     _Read<u64_le>(_var, addr); |     Read<u64_le>(_var, addr); | ||||||
|     return _var; |     return _var; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -278,19 +256,19 @@ u32 Read16_ZX(const u32 addr) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Write8(const u32 addr, const u8 data) { | void Write8(const u32 addr, const u8 data) { | ||||||
|     _Write<u8>(addr, data); |     Write<u8>(addr, data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Write16(const u32 addr, const u16 data) { | void Write16(const u32 addr, const u16 data) { | ||||||
|     _Write<u16_le>(addr, data); |     Write<u16_le>(addr, data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Write32(const u32 addr, const u32 data) { | void Write32(const u32 addr, const u32 data) { | ||||||
|     _Write<u32_le>(addr, data); |     Write<u32_le>(addr, data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Write64(const u32 addr, const u64 data) { | void Write64(const u32 addr, const u64 data) { | ||||||
|     _Write<u64_le>(addr, data); |     Write<u64_le>(addr, data); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void WriteBlock(const u32 addr, const u8* data, const int size) { | void WriteBlock(const u32 addr, const u8* data, const int size) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue