mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Kernel: Added preliminary support for address arbiters.
AddressArbiter: Added documentation comment, fixed whitespace issue. AddressArbiter: Fixed incorrect comment, reordered if-statement to be more clear. SVC: Removed trailing whitespace.
This commit is contained in:
		
							parent
							
								
									ba840d3200
								
							
						
					
					
						commit
						3eb89f3e98
					
				
					 7 changed files with 144 additions and 9 deletions
				
			
		|  | @ -34,6 +34,7 @@ set(SRCS    core.cpp | ||||||
|             hle/config_mem.cpp |             hle/config_mem.cpp | ||||||
|             hle/coprocessor.cpp |             hle/coprocessor.cpp | ||||||
|             hle/svc.cpp |             hle/svc.cpp | ||||||
|  |             hle/kernel/address_arbiter.cpp | ||||||
|             hle/kernel/archive.cpp |             hle/kernel/archive.cpp | ||||||
|             hle/kernel/event.cpp |             hle/kernel/event.cpp | ||||||
|             hle/kernel/kernel.cpp |             hle/kernel/kernel.cpp | ||||||
|  | @ -83,6 +84,7 @@ set(HEADERS core.h | ||||||
|             hle/coprocessor.h |             hle/coprocessor.h | ||||||
|             hle/hle.h |             hle/hle.h | ||||||
|             hle/svc.h |             hle/svc.h | ||||||
|  |             hle/kernel/address_arbiter.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 | ||||||
|  |  | ||||||
|  | @ -166,6 +166,7 @@ | ||||||
|     <ClCompile Include="hle\config_mem.cpp" /> |     <ClCompile Include="hle\config_mem.cpp" /> | ||||||
|     <ClCompile Include="hle\coprocessor.cpp" /> |     <ClCompile Include="hle\coprocessor.cpp" /> | ||||||
|     <ClCompile Include="hle\hle.cpp" /> |     <ClCompile Include="hle\hle.cpp" /> | ||||||
|  |     <ClCompile Include="hle\kernel\address_arbiter.cpp" /> | ||||||
|     <ClCompile Include="hle\kernel\archive.cpp" /> |     <ClCompile Include="hle\kernel\archive.cpp" /> | ||||||
|     <ClCompile Include="hle\kernel\event.cpp" /> |     <ClCompile Include="hle\kernel\event.cpp" /> | ||||||
|     <ClCompile Include="hle\kernel\kernel.cpp" /> |     <ClCompile Include="hle\kernel\kernel.cpp" /> | ||||||
|  | @ -219,6 +220,7 @@ | ||||||
|     <ClInclude Include="hle\coprocessor.h" /> |     <ClInclude Include="hle\coprocessor.h" /> | ||||||
|     <ClInclude Include="hle\function_wrappers.h" /> |     <ClInclude Include="hle\function_wrappers.h" /> | ||||||
|     <ClInclude Include="hle\hle.h" /> |     <ClInclude Include="hle\hle.h" /> | ||||||
|  |     <ClInclude Include="hle\kernel\address_arbiter.h" /> | ||||||
|     <ClInclude Include="hle\kernel\archive.h" /> |     <ClInclude Include="hle\kernel\archive.h" /> | ||||||
|     <ClInclude Include="hle\kernel\event.h" /> |     <ClInclude Include="hle\kernel\event.h" /> | ||||||
|     <ClInclude Include="hle\kernel\kernel.h" /> |     <ClInclude Include="hle\kernel\kernel.h" /> | ||||||
|  |  | ||||||
|  | @ -182,6 +182,9 @@ | ||||||
|     <ClCompile Include="hle\kernel\shared_memory.cpp"> |     <ClCompile Include="hle\kernel\shared_memory.cpp"> | ||||||
|       <Filter>hle\kernel</Filter> |       <Filter>hle\kernel</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="hle\kernel\address_arbiter.cpp"> | ||||||
|  |       <Filter>hle\kernel</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClInclude Include="arm\disassembler\arm_disasm.h"> |     <ClInclude Include="arm\disassembler\arm_disasm.h"> | ||||||
|  | @ -326,6 +329,9 @@ | ||||||
|     <ClInclude Include="hle\kernel\shared_memory.h"> |     <ClInclude Include="hle\kernel\shared_memory.h"> | ||||||
|       <Filter>hle\kernel</Filter> |       <Filter>hle\kernel</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="hle\kernel\address_arbiter.h"> | ||||||
|  |       <Filter>hle\kernel</Filter> | ||||||
|  |     </ClInclude> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <Text Include="CMakeLists.txt" /> |     <Text Include="CMakeLists.txt" /> | ||||||
|  |  | ||||||
							
								
								
									
										87
									
								
								src/core/hle/kernel/address_arbiter.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/core/hle/kernel/address_arbiter.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,87 @@ | ||||||
|  | // Copyright 2014 Citra Emulator Project
 | ||||||
|  | // Licensed under GPLv2
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include "common/common_types.h" | ||||||
|  | 
 | ||||||
|  | #include "core/mem_map.h" | ||||||
|  | 
 | ||||||
|  | #include "core/hle/hle.h" | ||||||
|  | #include "core/hle/kernel/address_arbiter.h" | ||||||
|  | #include "core/hle/kernel/thread.h" | ||||||
|  | 
 | ||||||
|  | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | // Kernel namespace
 | ||||||
|  | 
 | ||||||
|  | namespace Kernel { | ||||||
|  | 
 | ||||||
|  | class AddressArbiter : public Object { | ||||||
|  | public: | ||||||
|  |     const char* GetTypeName() const { return "Arbiter"; } | ||||||
|  |     const char* GetName() const { return name.c_str(); } | ||||||
|  | 
 | ||||||
|  |     static Kernel::HandleType GetStaticHandleType() { return HandleType::AddressArbiter; } | ||||||
|  |     Kernel::HandleType GetHandleType() const { return HandleType::AddressArbiter; } | ||||||
|  | 
 | ||||||
|  |     std::string name;   ///< Name of address arbiter object (optional)
 | ||||||
|  | 
 | ||||||
|  |     /**
 | ||||||
|  |      * 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; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | 
 | ||||||
|  | /// Arbitrate an address
 | ||||||
|  | Result ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { | ||||||
|  |     switch (type) { | ||||||
|  | 
 | ||||||
|  |     // Signal thread(s) waiting for arbitrate address...
 | ||||||
|  |     case ArbitrationType::Signal: | ||||||
|  |         // Negative value means resume all threads
 | ||||||
|  |         if (value < 0) { | ||||||
|  |             ArbitrateAllThreads(handle, address); | ||||||
|  |         } else { | ||||||
|  |             // Resume first N threads
 | ||||||
|  |             for(int i = 0; i < value; i++) | ||||||
|  |                 ArbitrateHighestPriorityThread(handle, address); | ||||||
|  |         } | ||||||
|  |         HLE::Reschedule(__func__); | ||||||
|  | 
 | ||||||
|  |     // Wait current thread (acquire the arbiter)...
 | ||||||
|  |     case ArbitrationType::WaitIfLessThan: | ||||||
|  |         if ((s32)Memory::Read32(address) <= value) { | ||||||
|  |             Kernel::WaitCurrentThread(WAITTYPE_ARB, handle); | ||||||
|  |             HLE::Reschedule(__func__); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     default: | ||||||
|  |         ERROR_LOG(KERNEL, "unknown type=%d", type); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Create an address arbiter
 | ||||||
|  | AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) { | ||||||
|  |     AddressArbiter* address_arbiter = new AddressArbiter; | ||||||
|  |     handle = Kernel::g_object_pool.Create(address_arbiter); | ||||||
|  |     address_arbiter->name = name; | ||||||
|  |     return address_arbiter; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Create an address arbiter
 | ||||||
|  | Handle CreateAddressArbiter(const std::string& name) { | ||||||
|  |     Handle handle; | ||||||
|  |     CreateAddressArbiter(handle, name); | ||||||
|  |     return handle; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace Kernel
 | ||||||
							
								
								
									
										36
									
								
								src/core/hle/kernel/address_arbiter.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/core/hle/kernel/address_arbiter.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | // 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" | ||||||
|  | 
 | ||||||
|  | // Address arbiters are an underlying kernel synchronization object that can be created/used via
 | ||||||
|  | // supervisor calls (SVCs). They function as sort of a global lock. Typically, games/other CTR
 | ||||||
|  | // applications use them as an underlying mechanism to implement thread-safe barriers, events, and
 | ||||||
|  | // semphores. 
 | ||||||
|  | 
 | ||||||
|  | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | // Kernel namespace
 | ||||||
|  | 
 | ||||||
|  | namespace Kernel { | ||||||
|  | 
 | ||||||
|  | /// Address arbitration types
 | ||||||
|  | enum class ArbitrationType : u32 { | ||||||
|  |     Signal, | ||||||
|  |     WaitIfLessThan, | ||||||
|  |     DecrementAndWaitIfLessThan, | ||||||
|  |     WaitIfLessThanWithTimeout, | ||||||
|  |     DecrementAndWaitIfLessThanWithTimeout, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /// Arbitrate an address
 | ||||||
|  | Result ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value); | ||||||
|  | 
 | ||||||
|  | /// Create an address arbiter
 | ||||||
|  | Handle CreateAddressArbiter(const std::string& name = "Unknown"); | ||||||
|  | 
 | ||||||
|  | } // namespace FileSys
 | ||||||
|  | @ -26,7 +26,7 @@ enum class HandleType : u32 { | ||||||
|     Redirection     = 6, |     Redirection     = 6, | ||||||
|     Thread          = 7, |     Thread          = 7, | ||||||
|     Process         = 8, |     Process         = 8, | ||||||
|     Arbiter         = 9, |     AddressArbiter  = 9, | ||||||
|     File            = 10, |     File            = 10, | ||||||
|     Semaphore       = 11, |     Semaphore       = 11, | ||||||
|     Archive         = 12, |     Archive         = 12, | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "core/mem_map.h" | #include "core/mem_map.h" | ||||||
| 
 | 
 | ||||||
|  | #include "core/hle/kernel/address_arbiter.h" | ||||||
| #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" | ||||||
|  | @ -175,18 +176,19 @@ Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wa | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Create an address arbiter (to allocate access to shared resources)
 | /// Create an address arbiter (to allocate access to shared resources)
 | ||||||
| Result CreateAddressArbiter(void* arbiter) { | Result CreateAddressArbiter(u32* arbiter) { | ||||||
|     ERROR_LOG(SVC, "(UNIMPLEMENTED) called"); |     DEBUG_LOG(SVC, "called"); | ||||||
|     Core::g_app_core->SetReg(1, 0xFABBDADD); |     Handle handle = Kernel::CreateAddressArbiter(); | ||||||
|  |     *arbiter = handle; | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Arbitrate address
 | /// Arbitrate address
 | ||||||
| Result ArbitrateAddress(Handle arbiter, u32 addr, u32 _type, u32 value, s64 nanoseconds) { | Result ArbitrateAddress(Handle arbiter, u32 address, u32 type, u32 value, s64 nanoseconds) { | ||||||
|     ERROR_LOG(SVC, "(UNIMPLEMENTED) called"); |     DEBUG_LOG(SVC, "called arbiter=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X, " | ||||||
|     ArbitrationType type = (ArbitrationType)_type; |         "nanoseconds=%d", arbiter, address, type, value, nanoseconds); | ||||||
|     Memory::Write32(addr, type); |     return Kernel::ArbitrateAddress(arbiter, static_cast<Kernel::ArbitrationType>(type), address,  | ||||||
|     return 0; |         value); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Used to output a message on a debug hardware unit - does nothing on a retail unit
 | /// Used to output a message on a debug hardware unit - does nothing on a retail unit
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue