aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/config_mem.cpp6
-rw-r--r--src/core/hle/config_mem.h2
-rw-r--r--src/core/hle/hle.cpp55
-rw-r--r--src/core/hle/hle.h27
-rw-r--r--src/core/hle/kernel/kernel.cpp11
-rw-r--r--src/core/hle/kernel/kernel.h5
-rw-r--r--src/core/hle/kernel/thread.cpp10
-rw-r--r--src/core/hle/kernel/timer.cpp5
-rw-r--r--src/core/hle/service/apt/apt.cpp17
-rw-r--r--src/core/hle/service/cfg/cfg.cpp6
-rw-r--r--src/core/hle/service/dsp_dsp.cpp28
-rw-r--r--src/core/hle/service/hid/hid.cpp22
-rw-r--r--src/core/hle/service/ir/ir.cpp6
-rw-r--r--src/core/hle/service/nwm_uds.cpp2
-rw-r--r--src/core/hle/service/ptm/ptm.cpp7
-rw-r--r--src/core/hle/service/ptm/ptm_sysm.cpp2
-rw-r--r--src/core/hle/service/service.cpp43
-rw-r--r--src/core/hle/service/service.h55
-rw-r--r--src/core/hle/service/y2r_u.cpp2
-rw-r--r--src/core/hle/shared_page.cpp5
-rw-r--r--src/core/hle/shared_page.h2
-rw-r--r--src/core/hle/svc.cpp37
-rw-r--r--src/core/hle/svc.h2
23 files changed, 187 insertions, 170 deletions
diff --git a/src/core/hle/config_mem.cpp b/src/core/hle/config_mem.cpp
index 40bae9346..9fcfcc285 100644
--- a/src/core/hle/config_mem.cpp
+++ b/src/core/hle/config_mem.cpp
@@ -61,12 +61,13 @@ template void Read<u16>(u16 &var, const u32 addr);
template void Read<u8>(u8 &var, const u32 addr);
void Init() {
+ memset(&config_mem, 0, sizeof(config_mem));
+
config_mem.update_flag = 0; // No update
config_mem.sys_core_ver = 0x2;
config_mem.unit_info = 0x1; // Bit 0 set for Retail
config_mem.prev_firm = 0;
config_mem.app_mem_type = 0x2; // Default app mem type is 0
- config_mem.unit_info = 0x1; // Bit 0 set for Retail
config_mem.app_mem_alloc = 0x06000000; // Set to 96MB, since some games use more than the default (64MB)
config_mem.base_mem_alloc = 0x01400000; // Default base memory is 20MB
config_mem.sys_mem_alloc = Memory::FCRAM_SIZE - (config_mem.app_mem_alloc + config_mem.base_mem_alloc);
@@ -77,4 +78,7 @@ void Init() {
config_mem.firm_sys_core_ver = 0x2;
}
+void Shutdown() {
+}
+
} // namespace
diff --git a/src/core/hle/config_mem.h b/src/core/hle/config_mem.h
index 94853901a..cbb478fb3 100644
--- a/src/core/hle/config_mem.h
+++ b/src/core/hle/config_mem.h
@@ -20,4 +20,6 @@ void Read(T &var, const u32 addr);
void Init();
+void Shutdown();
+
} // namespace
diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp
index 1aaeaa9c9..fdeb9a028 100644
--- a/src/core/hle/hle.cpp
+++ b/src/core/hle/hle.cpp
@@ -2,12 +2,11 @@
// 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"
@@ -18,35 +17,7 @@
namespace HLE {
-Common::Profiling::TimingCategory profiler_svc("SVC Calls");
-
-static std::vector<ModuleDef> g_module_db;
-
-bool g_reschedule = false; ///< 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());
- }
-}
+bool g_reschedule; ///< If true, immediately reschedules the CPU to a new thread
void Reschedule(const char *reason) {
DEBUG_ASSERT_MSG(reason != nullptr && strlen(reason) < 256, "Reschedule: Invalid or too long reason.");
@@ -62,31 +33,21 @@ 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() {
Service::Init();
-
- RegisterAllModules();
-
ConfigMem::Init();
SharedPage::Init();
+ g_reschedule = false;
+
LOG_DEBUG(Kernel, "initialized OK");
}
void Shutdown() {
+ ConfigMem::Shutdown();
+ SharedPage::Shutdown();
Service::Shutdown();
- g_module_db.clear();
-
LOG_DEBUG(Kernel, "shutdown OK");
}
diff --git a/src/core/hle/hle.h b/src/core/hle/hle.h
index 3f6f9a4b5..23de1aab7 100644
--- a/src/core/hle/hle.h
+++ b/src/core/hle/hle.h
@@ -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
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 6261b82b6..fca582bbe 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -14,11 +14,10 @@
namespace Kernel {
-unsigned int Object::next_object_id = 0;
-
-SharedPtr<Thread> g_main_thread = nullptr;
+unsigned int Object::next_object_id;
+SharedPtr<Thread> g_main_thread;
HandleTable g_handle_table;
-u64 g_program_id = 0;
+u64 g_program_id;
void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
@@ -138,6 +137,10 @@ void HandleTable::Clear() {
void Init() {
Kernel::ThreadingInit();
Kernel::TimersInit();
+
+ Object::next_object_id = 0;
+ g_program_id = 0;
+ g_main_thread = nullptr;
}
/// Shutdown the kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 2d295ea00..ab06fa025 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -95,12 +95,13 @@ public:
return false;
}
+public:
+ static unsigned int next_object_id;
+
private:
friend void intrusive_ptr_add_ref(Object*);
friend void intrusive_ptr_release(Object*);
- static unsigned int next_object_id;
-
unsigned int ref_count = 0;
unsigned int object_id = next_object_id++;
};
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 33d66b986..d678f5f6f 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -23,7 +23,7 @@
namespace Kernel {
/// Event type for the thread wake up event
-static int ThreadWakeupEventType = -1;
+static int ThreadWakeupEventType;
bool Thread::ShouldWait() {
return status != THREADSTATUS_DEAD;
@@ -42,7 +42,7 @@ static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> ready_queue;
static Thread* current_thread;
// The first available thread id at startup
-static u32 next_thread_id = 1;
+static u32 next_thread_id;
/**
* Creates a new thread ID
@@ -497,6 +497,12 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {
void ThreadingInit() {
ThreadWakeupEventType = CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
+ current_thread = nullptr;
+ next_thread_id = 1;
+
+ thread_list.clear();
+ ready_queue.clear();
+
// Setup the idle thread
SetupIdleThread();
}
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 610e26a3c..36979248d 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -12,7 +12,7 @@
namespace Kernel {
/// The event type of the generic timer callback event
-static int timer_callback_event_type = -1;
+static int timer_callback_event_type;
// TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future, allowing
// us to simply use a pool index or similar.
static Kernel::HandleTable timer_callback_handle_table;
@@ -66,7 +66,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
SharedPtr<Timer> timer = timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle));
if (timer == nullptr) {
- LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08X", timer_handle);
+ LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08lX", timer_handle);
return;
}
@@ -89,6 +89,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
}
void TimersInit() {
+ timer_callback_handle_table.Clear();
timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback);
}
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 190c5df7a..98ae80b3a 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -28,15 +28,15 @@ namespace APT {
static const VAddr SHARED_FONT_VADDR = 0x18000000;
/// Handle to shared memory region designated to for shared system font
-static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem = nullptr;
+static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
-static Kernel::SharedPtr<Kernel::Mutex> lock = nullptr;
-static Kernel::SharedPtr<Kernel::Event> notification_event = nullptr; ///< APT notification event
-static Kernel::SharedPtr<Kernel::Event> start_event = nullptr; ///< APT start event
+static Kernel::SharedPtr<Kernel::Mutex> lock;
+static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
+static Kernel::SharedPtr<Kernel::Event> start_event; ///< APT start event
static std::vector<u8> shared_font;
-static u32 cpu_percent = 0; ///< CPU time available to the running application
+static u32 cpu_percent; ///< CPU time available to the running application
void Initialize(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
@@ -309,6 +309,7 @@ void Init() {
}
lock = Kernel::Mutex::Create(false, "APT_U:Lock");
+
cpu_percent = 0;
// TODO(bunnei): Check if these are created in Initialize or on APT process startup.
@@ -317,7 +318,11 @@ void Init() {
}
void Shutdown() {
-
+ shared_font.clear();
+ shared_font_mem = nullptr;
+ lock = nullptr;
+ notification_event = nullptr;
+ start_event = nullptr;
}
} // namespace APT
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index fe1245fe8..5eccdecf7 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -53,12 +53,12 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) {
});
if (itr == std::end(config->block_entries)) {
- LOG_ERROR(Service_CFG, "Config block %u with flags %u was not found", block_id, flag);
+ LOG_ERROR(Service_CFG, "Config block 0x%X with flags %u and size %u was not found", block_id, flag, size);
return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent);
}
if (itr->size != size) {
- LOG_ERROR(Service_CFG, "Invalid size %u for config block %u with flags %u", size, block_id, flag);
+ LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size, block_id, flag);
return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent);
}
@@ -207,6 +207,7 @@ void Init() {
// Initialize the Username block
// TODO(Subv): Initialize this directly in the variable when MSVC supports char16_t string literals
+ memset(&CONSOLE_USERNAME_BLOCK, 0, sizeof(CONSOLE_USERNAME_BLOCK));
CONSOLE_USERNAME_BLOCK.ng_word = 0;
CONSOLE_USERNAME_BLOCK.zero = 0;
@@ -219,7 +220,6 @@ void Init() {
}
void Shutdown() {
-
}
} // namespace CFG
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index f16f84e67..2e759a3e3 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -11,7 +11,7 @@
namespace DSP_DSP {
-static u32 read_pipe_count = 0;
+static u32 read_pipe_count;
static Kernel::SharedPtr<Kernel::Event> semaphore_event;
static Kernel::SharedPtr<Kernel::Event> interrupt_event;
@@ -42,7 +42,7 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) {
cmd_buff[1] = 0; // No error
cmd_buff[2] = (addr << 1) + (Memory::DSP_MEMORY_VADDR + 0x40000);
- LOG_WARNING(Service_DSP, "(STUBBED) called with address %u", addr);
+ LOG_WARNING(Service_DSP, "(STUBBED) called with address 0x%08X", addr);
}
/**
@@ -60,12 +60,19 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) {
static void LoadComponent(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 size = cmd_buff[1];
+ u32 unk1 = cmd_buff[2];
+ u32 unk2 = cmd_buff[3];
+ u32 new_size = cmd_buff[4];
+ u32 buffer = cmd_buff[5];
+
cmd_buff[1] = 0; // No error
cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware
// TODO(bunnei): Implement real DSP firmware loading
- LOG_WARNING(Service_DSP, "(STUBBED) called");
+ LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%X, unk1=0x%08X, unk2=0x%08X, new_size=0x%X, buffer=0x%08X",
+ size, unk1, unk2, new_size, buffer);
}
/**
@@ -106,7 +113,7 @@ static void FlushDataCache(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- LOG_DEBUG(Service_DSP, "(STUBBED) called address=0x%08X, size=0x%08X, process=0x%08X",
+ LOG_DEBUG(Service_DSP, "(STUBBED) called address=0x%08X, size=0x%X, process=0x%08X",
address, size, process);
}
@@ -122,6 +129,10 @@ static void FlushDataCache(Service::Interface* self) {
static void RegisterInterruptEvents(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 param0 = cmd_buff[1];
+ u32 param1 = cmd_buff[2];
+ u32 event_handle = cmd_buff[4];
+
auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
if (evt != nullptr) {
interrupt_event = evt;
@@ -133,7 +144,7 @@ static void RegisterInterruptEvents(Service::Interface* self) {
cmd_buff[1] = -1;
}
- LOG_WARNING(Service_DSP, "(STUBBED) called");
+ LOG_WARNING(Service_DSP, "(STUBBED) called param0=%u, param1=%u, event_handle=0x%08X", param0, param1, event_handle);
}
/**
@@ -174,7 +185,7 @@ static void WriteProcessPipe(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%08X, new_size=0x%08X, buffer=0x%08X",
+ LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%X, new_size=0x%X, buffer=0x%08X",
number, size, new_size, buffer);
}
@@ -192,6 +203,8 @@ static void WriteProcessPipe(Service::Interface* self) {
static void ReadPipeIfPossible(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
+ u32 unk1 = cmd_buff[1];
+ u32 unk2 = cmd_buff[2];
u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size
VAddr addr = cmd_buff[0x41];
@@ -217,7 +230,8 @@ static void ReadPipeIfPossible(Service::Interface* self) {
cmd_buff[1] = 0; // No error
cmd_buff[2] = (read_pipe_count - initial_size) * sizeof(u16);
- LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%08X, buffer=0x%08X", size, addr);
+ LOG_WARNING(Service_DSP, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, size=0x%X, buffer=0x%08X",
+ unk1, unk2, size, addr);
}
/**
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 9ca5d13d4..0f30f743a 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -20,17 +20,17 @@ namespace HID {
static const int MAX_CIRCLEPAD_POS = 0x9C; ///< Max value for a circle pad position
// Handle to shared memory region designated to HID_User service
-static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem = nullptr;
+static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
// Event handles
-static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1 = nullptr;
-static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2 = nullptr;
-static Kernel::SharedPtr<Kernel::Event> event_accelerometer = nullptr;
-static Kernel::SharedPtr<Kernel::Event> event_gyroscope = nullptr;
-static Kernel::SharedPtr<Kernel::Event> event_debug_pad = nullptr;
+static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1;
+static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2;
+static Kernel::SharedPtr<Kernel::Event> event_accelerometer;
+static Kernel::SharedPtr<Kernel::Event> event_gyroscope;
+static Kernel::SharedPtr<Kernel::Event> event_debug_pad;
-static u32 next_pad_index = 0;
-static u32 next_touch_index = 0;
+static u32 next_pad_index;
+static u32 next_touch_index;
// TODO(peachum):
// Add a method for setting analog input from joystick device for the circle Pad.
@@ -175,6 +175,12 @@ void Init() {
}
void Shutdown() {
+ shared_mem = nullptr;
+ event_pad_or_touch_1 = nullptr;
+ event_pad_or_touch_2 = nullptr;
+ event_accelerometer = nullptr;
+ event_gyroscope = nullptr;
+ event_debug_pad = nullptr;
}
} // namespace HID
diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp
index 58dfd8e1a..15ac477ef 100644
--- a/src/core/hle/service/ir/ir.cpp
+++ b/src/core/hle/service/ir/ir.cpp
@@ -15,8 +15,8 @@
namespace Service {
namespace IR {
-static Kernel::SharedPtr<Kernel::Event> handle_event = nullptr;
-static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr;
+static Kernel::SharedPtr<Kernel::Event> handle_event;
+static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory;
void GetHandles(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
@@ -41,6 +41,8 @@ void Init() {
}
void Shutdown() {
+ shared_memory = nullptr;
+ handle_event = nullptr;
}
} // namespace IR
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp
index 1cee81ab2..4b06efc3a 100644
--- a/src/core/hle/service/nwm_uds.cpp
+++ b/src/core/hle/service/nwm_uds.cpp
@@ -11,7 +11,7 @@
namespace NWM_UDS {
-static Kernel::SharedPtr<Kernel::Event> handle_event = nullptr;
+static Kernel::SharedPtr<Kernel::Event> handle_event;
/**
* NWM_UDS::Shutdown service function
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index 57a301bec..d44510c1b 100644
--- a/src/core/hle/service/ptm/ptm.cpp
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -18,9 +18,9 @@ static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 };
/// Id of the SharedExtData archive used by the PTM process
static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0};
-static bool shell_open = true;
+static bool shell_open;
-static bool battery_is_charging = true;
+static bool battery_is_charging;
u32 GetAdapterState() {
// TODO(purpasmart96): This function is only a stub,
@@ -43,6 +43,9 @@ void Init() {
AddService(new PTM_Sysm_Interface);
AddService(new PTM_U_Interface);
+ shell_open = true;
+ battery_is_charging = true;
+
// Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't exist
FileSys::Path archive_path(ptm_shared_extdata_id);
auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp
index 2d841f69c..13322bdbb 100644
--- a/src/core/hle/service/ptm/ptm_sysm.cpp
+++ b/src/core/hle/service/ptm/ptm_sysm.cpp
@@ -16,7 +16,7 @@ namespace PTM {
* 1: Result code, 0 on success, otherwise error code
* 2: Whether the system is going through a power off
*/
-void IsLegacyPowerOff(Service::Interface* self) {
+static void IsLegacyPowerOff(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = RESULT_SUCCESS.raw;
cmd_buff[2] = 0;
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 134ff1740..d50327cb9 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -51,6 +51,49 @@ namespace Service {
std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports;
std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
+/**
+ * Creates a function string for logging, complete with the name (or header code, depending
+ * on what's passed in) the port name, and all the cmd_buff arguments.
+ */
+static std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) {
+ // Number of params == bits 0-5 + bits 6-11
+ int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F);
+
+ std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name);
+ for (int i = 1; i <= num_params; ++i) {
+ function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]);
+ }
+ return function_string;
+}
+
+ResultVal<bool> Interface::SyncRequest() {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ auto itr = m_functions.find(cmd_buff[0]);
+
+ if (itr == m_functions.end() || itr->second.func == nullptr) {
+ std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name;
+ LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str());
+
+ // TODO(bunnei): Hack - ignore error
+ cmd_buff[1] = 0;
+ return MakeResult<bool>(false);
+ } else {
+ LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str());
+ }
+
+ itr->second.func(this);
+
+ return MakeResult<bool>(false); // TODO: Implement return from actual function
+}
+
+void Interface::Register(const FunctionInfo* functions, size_t n) {
+ m_functions.reserve(n);
+ for (size_t i = 0; i < n; ++i) {
+ // Usually this array is sorted by id already, so hint to instead at the end
+ m_functions.emplace_hint(m_functions.cend(), functions[i].id, functions[i]);
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// Module interface
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index bfe16ebad..21ada67b5 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -4,20 +4,15 @@
#pragma once
-#include <algorithm>
#include <string>
#include <unordered_map>
-#include <vector>
#include <boost/container/flat_map.hpp>
#include "common/common.h"
-#include "common/string_util.h"
-#include "core/mem_map.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/session.h"
-#include "core/hle/svc.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// Namespace Service
@@ -26,31 +21,11 @@ namespace Service {
static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters)
-class Manager;
-
/// Interface to a CTROS service
class Interface : public Kernel::Session {
// TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be
// just something that encapsulates a session and acts as a helper to implement service
// processes.
-
- friend class Manager;
-
- /**
- * Creates a function string for logging, complete with the name (or header code, depending
- * on what's passed in) the port name, and all the cmd_buff arguments.
- */
- std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) {
- // Number of params == bits 0-5 + bits 6-11
- int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F);
-
- std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name);
- for (int i = 1; i <= num_params; ++i) {
- function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]);
- }
- return function_string;
- }
-
public:
std::string GetName() const override { return GetPortName(); }
@@ -70,25 +45,7 @@ public:
return "[UNKNOWN SERVICE PORT]";
}
- ResultVal<bool> SyncRequest() override {
- u32* cmd_buff = Kernel::GetCommandBuffer();
- auto itr = m_functions.find(cmd_buff[0]);
-
- if (itr == m_functions.end() || itr->second.func == nullptr) {
- std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name;
- LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str());
-
- // TODO(bunnei): Hack - ignore error
- cmd_buff[1] = 0;
- return MakeResult<bool>(false);
- } else {
- LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str());
- }
-
- itr->second.func(this);
-
- return MakeResult<bool>(false); // TODO: Implement return from actual function
- }
+ ResultVal<bool> SyncRequest() override;
protected:
@@ -96,14 +53,12 @@ protected:
* Registers the functions in the service
*/
template <size_t N>
- void Register(const FunctionInfo (&functions)[N]) {
- m_functions.reserve(N);
- for (auto& fn : functions) {
- // Usually this array is sorted by id already, so hint to instead at the end
- m_functions.emplace_hint(m_functions.cend(), fn.id, fn);
- }
+ inline void Register(const FunctionInfo (&functions)[N]) {
+ Register(functions, N);
}
+ void Register(const FunctionInfo* functions, size_t n);
+
private:
boost::container::flat_map<u32, FunctionInfo> m_functions;
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
index 6607965e1..33ecf64a2 100644
--- a/src/core/hle/service/y2r_u.cpp
+++ b/src/core/hle/service/y2r_u.cpp
@@ -11,7 +11,7 @@
namespace Y2R_U {
-static Kernel::SharedPtr<Kernel::Event> completion_event = 0;
+static Kernel::SharedPtr<Kernel::Event> completion_event;
/**
* Y2R_U::IsBusyConversion service function
diff --git a/src/core/hle/shared_page.cpp b/src/core/hle/shared_page.cpp
index 568dad684..94fae2551 100644
--- a/src/core/hle/shared_page.cpp
+++ b/src/core/hle/shared_page.cpp
@@ -62,6 +62,8 @@ template void Read<u16>(u16 &var, const u32 addr);
template void Read<u8>(u8 &var, const u32 addr);
void Set3DSlider(float amount) {
+ memset(&shared_page, 0, sizeof(shared_page));
+
shared_page.sliderstate_3d = amount;
shared_page.ledstate_3d = (amount == 0.0f); // off when non-zero
}
@@ -71,4 +73,7 @@ void Init() {
Set3DSlider(0.0f);
}
+void Shutdown() {
+}
+
} // namespace
diff --git a/src/core/hle/shared_page.h b/src/core/hle/shared_page.h
index 8f93545ec..1b6e4e581 100644
--- a/src/core/hle/shared_page.h
+++ b/src/core/hle/shared_page.h
@@ -23,4 +23,6 @@ void Set3DSlider(float amount);
void Init();
+void Shutdown();
+
} // namespace
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 76e9b171a..2da488d83 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -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
diff --git a/src/core/hle/svc.h b/src/core/hle/svc.h
index 5d020a5ba..4389aa73d 100644
--- a/src/core/hle/svc.h
+++ b/src/core/hle/svc.h
@@ -41,6 +41,6 @@ enum ArbitrationType {
namespace SVC {
-void Register();
+void CallSVC(u32 opcode);
} // namespace