mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +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/coprocessor.cpp | ||||
|             hle/svc.cpp | ||||
|             hle/kernel/address_arbiter.cpp | ||||
|             hle/kernel/archive.cpp | ||||
|             hle/kernel/event.cpp | ||||
|             hle/kernel/kernel.cpp | ||||
|  | @ -83,6 +84,7 @@ set(HEADERS core.h | |||
|             hle/coprocessor.h | ||||
|             hle/hle.h | ||||
|             hle/svc.h | ||||
|             hle/kernel/address_arbiter.h | ||||
|             hle/kernel/archive.h | ||||
|             hle/kernel/kernel.h | ||||
|             hle/kernel/mutex.h | ||||
|  |  | |||
|  | @ -166,6 +166,7 @@ | |||
|     <ClCompile Include="hle\config_mem.cpp" /> | ||||
|     <ClCompile Include="hle\coprocessor.cpp" /> | ||||
|     <ClCompile Include="hle\hle.cpp" /> | ||||
|     <ClCompile Include="hle\kernel\address_arbiter.cpp" /> | ||||
|     <ClCompile Include="hle\kernel\archive.cpp" /> | ||||
|     <ClCompile Include="hle\kernel\event.cpp" /> | ||||
|     <ClCompile Include="hle\kernel\kernel.cpp" /> | ||||
|  | @ -219,6 +220,7 @@ | |||
|     <ClInclude Include="hle\coprocessor.h" /> | ||||
|     <ClInclude Include="hle\function_wrappers.h" /> | ||||
|     <ClInclude Include="hle\hle.h" /> | ||||
|     <ClInclude Include="hle\kernel\address_arbiter.h" /> | ||||
|     <ClInclude Include="hle\kernel\archive.h" /> | ||||
|     <ClInclude Include="hle\kernel\event.h" /> | ||||
|     <ClInclude Include="hle\kernel\kernel.h" /> | ||||
|  |  | |||
|  | @ -182,6 +182,9 @@ | |||
|     <ClCompile Include="hle\kernel\shared_memory.cpp"> | ||||
|       <Filter>hle\kernel</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="hle\kernel\address_arbiter.cpp"> | ||||
|       <Filter>hle\kernel</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="arm\disassembler\arm_disasm.h"> | ||||
|  | @ -326,6 +329,9 @@ | |||
|     <ClInclude Include="hle\kernel\shared_memory.h"> | ||||
|       <Filter>hle\kernel</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="hle\kernel\address_arbiter.h"> | ||||
|       <Filter>hle\kernel</Filter> | ||||
|     </ClInclude> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <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, | ||||
|     Thread          = 7, | ||||
|     Process         = 8, | ||||
|     Arbiter         = 9, | ||||
|     AddressArbiter  = 9, | ||||
|     File            = 10, | ||||
|     Semaphore       = 11, | ||||
|     Archive         = 12, | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| 
 | ||||
| #include "core/mem_map.h" | ||||
| 
 | ||||
| #include "core/hle/kernel/address_arbiter.h" | ||||
| #include "core/hle/kernel/event.h" | ||||
| #include "core/hle/kernel/kernel.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)
 | ||||
| Result CreateAddressArbiter(void* arbiter) { | ||||
|     ERROR_LOG(SVC, "(UNIMPLEMENTED) called"); | ||||
|     Core::g_app_core->SetReg(1, 0xFABBDADD); | ||||
| Result CreateAddressArbiter(u32* arbiter) { | ||||
|     DEBUG_LOG(SVC, "called"); | ||||
|     Handle handle = Kernel::CreateAddressArbiter(); | ||||
|     *arbiter = handle; | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /// Arbitrate address
 | ||||
| Result ArbitrateAddress(Handle arbiter, u32 addr, u32 _type, u32 value, s64 nanoseconds) { | ||||
|     ERROR_LOG(SVC, "(UNIMPLEMENTED) called"); | ||||
|     ArbitrationType type = (ArbitrationType)_type; | ||||
|     Memory::Write32(addr, type); | ||||
|     return 0; | ||||
| Result ArbitrateAddress(Handle arbiter, u32 address, u32 type, u32 value, s64 nanoseconds) { | ||||
|     DEBUG_LOG(SVC, "called arbiter=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X, " | ||||
|         "nanoseconds=%d", arbiter, address, type, value, nanoseconds); | ||||
|     return Kernel::ArbitrateAddress(arbiter, static_cast<Kernel::ArbitrationType>(type), address,  | ||||
|         value); | ||||
| } | ||||
| 
 | ||||
| /// 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