mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Merge pull request #720 from yuriks/svc-cleanup
HLE: Clean up SVC dispatch mechanism
This commit is contained in:
		
						commit
						c4abfe893b
					
				
					 5 changed files with 40 additions and 79 deletions
				
			
		|  | @ -11,7 +11,7 @@ | ||||||
| #include "common/profiler.h" | #include "common/profiler.h" | ||||||
| 
 | 
 | ||||||
| #include "core/mem_map.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/disassembler/arm_disasm.h" | ||||||
| #include "core/arm/dyncom/arm_dyncom_interpreter.h" | #include "core/arm/dyncom/arm_dyncom_interpreter.h" | ||||||
| #include "core/arm/dyncom/arm_dyncom_thumb.h" | #include "core/arm/dyncom/arm_dyncom_thumb.h" | ||||||
|  | @ -6234,7 +6234,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | ||||||
|     SWI_INST: |     SWI_INST: | ||||||
|     { |     { | ||||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |         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); |         cpu->Reg[15] += GET_INST_SIZE(cpu); | ||||||
|  |  | ||||||
|  | @ -2,53 +2,23 @@ | ||||||
| // Licensed under GPLv2 or any later version
 | // Licensed under GPLv2 or any later version
 | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include <vector> | #include "common/assert.h" | ||||||
| 
 | #include "common/logging/log.h" | ||||||
| #include "common/profiler.h" |  | ||||||
| 
 | 
 | ||||||
| #include "core/arm/arm_interface.h" | #include "core/arm/arm_interface.h" | ||||||
| #include "core/mem_map.h" | #include "core/core.h" | ||||||
| #include "core/hle/hle.h" | #include "core/hle/hle.h" | ||||||
| #include "core/hle/config_mem.h" | #include "core/hle/config_mem.h" | ||||||
| #include "core/hle/shared_page.h" | #include "core/hle/shared_page.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
| #include "core/hle/service/service.h" | #include "core/hle/service/service.h" | ||||||
| #include "core/hle/svc.h" |  | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
| namespace HLE { | 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
 | 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) { | void Reschedule(const char *reason) { | ||||||
|     DEBUG_ASSERT_MSG(reason != nullptr && strlen(reason) < 256, "Reschedule: Invalid or too long 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; |     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() { | void Init() { | ||||||
|     RegisterAllModules(); |  | ||||||
| 
 |  | ||||||
|     Service::Init(); |     Service::Init(); | ||||||
|     ConfigMem::Init(); |     ConfigMem::Init(); | ||||||
|     SharedPage::Init(); |     SharedPage::Init(); | ||||||
|  | @ -89,8 +48,6 @@ void Shutdown() { | ||||||
|     SharedPage::Shutdown(); |     SharedPage::Shutdown(); | ||||||
|     Service::Shutdown(); |     Service::Shutdown(); | ||||||
| 
 | 
 | ||||||
|     g_module_db.clear(); |  | ||||||
| 
 |  | ||||||
|     LOG_DEBUG(Kernel, "shutdown OK"); |     LOG_DEBUG(Kernel, "shutdown OK"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,40 +4,13 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <string> |  | ||||||
| 
 |  | ||||||
| #include "common/common_types.h" |  | ||||||
| #include "core/core.h" |  | ||||||
| 
 |  | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////
 |  | ||||||
| 
 |  | ||||||
| namespace HLE { | namespace HLE { | ||||||
| 
 | 
 | ||||||
| extern bool g_reschedule;   ///< If true, immediately reschedules the CPU to a new thread
 | 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 Reschedule(const char *reason); | ||||||
| 
 | 
 | ||||||
| void Init(); | void Init(); | ||||||
| 
 |  | ||||||
| void Shutdown(); | void Shutdown(); | ||||||
| 
 | 
 | ||||||
| } // namespace
 | } // namespace
 | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <map> | #include <map> | ||||||
| 
 | 
 | ||||||
|  | #include "common/profiler.h" | ||||||
| #include "common/string_util.h" | #include "common/string_util.h" | ||||||
| #include "common/symbols.h" | #include "common/symbols.h" | ||||||
| 
 | 
 | ||||||
|  | @ -606,7 +607,17 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 | ||||||
|     return RESULT_SUCCESS; |     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"}, |     {0x00, nullptr,                         "Unknown"}, | ||||||
|     {0x01, HLE::Wrap<ControlMemory>,        "ControlMemory"}, |     {0x01, HLE::Wrap<ControlMemory>,        "ControlMemory"}, | ||||||
|     {0x02, HLE::Wrap<QueryMemory>,          "QueryMemory"}, |     {0x02, HLE::Wrap<QueryMemory>,          "QueryMemory"}, | ||||||
|  | @ -735,8 +746,28 @@ const HLE::FunctionDef SVC_Table[] = { | ||||||
|     {0x7D, nullptr,                         "QueryProcessMemory"}, |     {0x7D, nullptr,                         "QueryProcessMemory"}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void Register() { | Common::Profiling::TimingCategory profiler_svc("SVC Calls"); | ||||||
|     HLE::RegisterModule("SVC_Table", ARRAY_SIZE(SVC_Table), SVC_Table); | 
 | ||||||
|  | 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
 | } // namespace
 | ||||||
|  |  | ||||||
|  | @ -41,6 +41,6 @@ enum ArbitrationType { | ||||||
| 
 | 
 | ||||||
| namespace SVC { | namespace SVC { | ||||||
| 
 | 
 | ||||||
| void Register(); | void CallSVC(u32 opcode); | ||||||
| 
 | 
 | ||||||
| } // namespace
 | } // namespace
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue