mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	HLE: Clean up SVC dispatch mechanism
This commit is contained in:
		
							parent
							
								
									9cdfe5d864
								
							
						
					
					
						commit
						ecff2351a1
					
				
					 5 changed files with 40 additions and 79 deletions
				
			
		|  | @ -11,7 +11,7 @@ | |||
| #include "common/profiler.h" | ||||
| 
 | ||||
| #include "core/mem_map.h" | ||||
| #include "core/hle/hle.h" | ||||
| #include "core/hle/svc.h" | ||||
| #include "core/arm/disassembler/arm_disasm.h" | ||||
| #include "core/arm/dyncom/arm_dyncom_interpreter.h" | ||||
| #include "core/arm/dyncom/arm_dyncom_thumb.h" | ||||
|  | @ -6234,7 +6234,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     SWI_INST: | ||||
|     { | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             HLE::CallSVC(Memory::Read32(cpu->Reg[15])); | ||||
|             SVC::CallSVC(Memory::Read32(cpu->Reg[15])); | ||||
|         } | ||||
| 
 | ||||
|         cpu->Reg[15] += GET_INST_SIZE(cpu); | ||||
|  |  | |||
|  | @ -2,53 +2,23 @@ | |||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <vector> | ||||
| 
 | ||||
| #include "common/profiler.h" | ||||
| #include "common/assert.h" | ||||
| #include "common/logging/log.h" | ||||
| 
 | ||||
| #include "core/arm/arm_interface.h" | ||||
| #include "core/mem_map.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/hle.h" | ||||
| #include "core/hle/config_mem.h" | ||||
| #include "core/hle/shared_page.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/svc.h" | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| namespace HLE { | ||||
| 
 | ||||
| Common::Profiling::TimingCategory profiler_svc("SVC Calls"); | ||||
| 
 | ||||
| static std::vector<ModuleDef> g_module_db; | ||||
| 
 | ||||
| bool g_reschedule; ///< If true, immediately reschedules the CPU to a new thread
 | ||||
| 
 | ||||
| static const FunctionDef* GetSVCInfo(u32 opcode) { | ||||
|     u32 func_num = opcode & 0xFFFFFF; // 8 bits
 | ||||
|     if (func_num > 0xFF) { | ||||
|         LOG_ERROR(Kernel_SVC,"unknown svc=0x%02X", func_num); | ||||
|         return nullptr; | ||||
|     } | ||||
|     return &g_module_db[0].func_table[func_num]; | ||||
| } | ||||
| 
 | ||||
| void CallSVC(u32 opcode) { | ||||
|     Common::Profiling::ScopeTimer timer_svc(profiler_svc); | ||||
| 
 | ||||
|     const FunctionDef *info = GetSVCInfo(opcode); | ||||
| 
 | ||||
|     if (!info) { | ||||
|         return; | ||||
|     } | ||||
|     if (info->func) { | ||||
|         info->func(); | ||||
|     } else { | ||||
|         LOG_ERROR(Kernel_SVC, "unimplemented SVC function %s(..)", info->name.c_str()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Reschedule(const char *reason) { | ||||
|     DEBUG_ASSERT_MSG(reason != nullptr && strlen(reason) < 256, "Reschedule: Invalid or too long reason."); | ||||
| 
 | ||||
|  | @ -63,18 +33,7 @@ void Reschedule(const char *reason) { | |||
|     g_reschedule = true; | ||||
| } | ||||
| 
 | ||||
| void RegisterModule(std::string name, int num_functions, const FunctionDef* func_table) { | ||||
|     ModuleDef module = {name, num_functions, func_table}; | ||||
|     g_module_db.push_back(module); | ||||
| } | ||||
| 
 | ||||
| static void RegisterAllModules() { | ||||
|     SVC::Register(); | ||||
| } | ||||
| 
 | ||||
| void Init() { | ||||
|     RegisterAllModules(); | ||||
| 
 | ||||
|     Service::Init(); | ||||
|     ConfigMem::Init(); | ||||
|     SharedPage::Init(); | ||||
|  | @ -89,8 +48,6 @@ void Shutdown() { | |||
|     SharedPage::Shutdown(); | ||||
|     Service::Shutdown(); | ||||
| 
 | ||||
|     g_module_db.clear(); | ||||
| 
 | ||||
|     LOG_DEBUG(Kernel, "shutdown OK"); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,40 +4,13 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <string> | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "core/core.h" | ||||
| 
 | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| namespace HLE { | ||||
| 
 | ||||
| extern bool g_reschedule;   ///< If true, immediately reschedules the CPU to a new thread
 | ||||
| 
 | ||||
| typedef u32 Addr; | ||||
| typedef void (*Func)(); | ||||
| 
 | ||||
| struct FunctionDef { | ||||
|     u32                 id; | ||||
|     Func                func; | ||||
|     std::string         name; | ||||
| }; | ||||
| 
 | ||||
| struct ModuleDef { | ||||
|     std::string         name; | ||||
|     int                 num_funcs; | ||||
|     const FunctionDef*  func_table; | ||||
| }; | ||||
| 
 | ||||
| void RegisterModule(std::string name, int num_functions, const FunctionDef *func_table); | ||||
| 
 | ||||
| void CallSVC(u32 opcode); | ||||
| 
 | ||||
| void Reschedule(const char *reason); | ||||
| 
 | ||||
| void Init(); | ||||
| 
 | ||||
| void Shutdown(); | ||||
| 
 | ||||
| } // namespace
 | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| 
 | ||||
| #include <map> | ||||
| 
 | ||||
| #include "common/profiler.h" | ||||
| #include "common/string_util.h" | ||||
| #include "common/symbols.h" | ||||
| 
 | ||||
|  | @ -606,7 +607,17 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 | |||
|     return RESULT_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| const HLE::FunctionDef SVC_Table[] = { | ||||
| namespace { | ||||
|     struct FunctionDef { | ||||
|         using Func = void(); | ||||
| 
 | ||||
|         u32         id; | ||||
|         Func*       func; | ||||
|         const char* name; | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| static const FunctionDef SVC_Table[] = { | ||||
|     {0x00, nullptr,                         "Unknown"}, | ||||
|     {0x01, HLE::Wrap<ControlMemory>,        "ControlMemory"}, | ||||
|     {0x02, HLE::Wrap<QueryMemory>,          "QueryMemory"}, | ||||
|  | @ -735,8 +746,28 @@ const HLE::FunctionDef SVC_Table[] = { | |||
|     {0x7D, nullptr,                         "QueryProcessMemory"}, | ||||
| }; | ||||
| 
 | ||||
| void Register() { | ||||
|     HLE::RegisterModule("SVC_Table", ARRAY_SIZE(SVC_Table), SVC_Table); | ||||
| Common::Profiling::TimingCategory profiler_svc("SVC Calls"); | ||||
| 
 | ||||
| static const FunctionDef* GetSVCInfo(u32 opcode) { | ||||
|     u32 func_num = opcode & 0xFFFFFF; // 8 bits
 | ||||
|     if (func_num >= ARRAY_SIZE(SVC_Table)) { | ||||
|         LOG_ERROR(Kernel_SVC, "unknown svc=0x%02X", func_num); | ||||
|         return nullptr; | ||||
|     } | ||||
|     return &SVC_Table[func_num]; | ||||
| } | ||||
| 
 | ||||
| void CallSVC(u32 opcode) { | ||||
|     Common::Profiling::ScopeTimer timer_svc(profiler_svc); | ||||
| 
 | ||||
|     const FunctionDef *info = GetSVCInfo(opcode); | ||||
|     if (info) { | ||||
|         if (info->func) { | ||||
|             info->func(); | ||||
|         } else { | ||||
|             LOG_ERROR(Kernel_SVC, "unimplemented SVC function %s(..)", info->name); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } // namespace
 | ||||
|  |  | |||
|  | @ -41,6 +41,6 @@ enum ArbitrationType { | |||
| 
 | ||||
| namespace SVC { | ||||
| 
 | ||||
| void Register(); | ||||
| void CallSVC(u32 opcode); | ||||
| 
 | ||||
| } // namespace
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue