diff options
-rw-r--r-- | src/citra_qt/configure_general.ui | 40 | ||||
-rw-r--r-- | src/citra_qt/configure_graphics.ui | 4 | ||||
-rw-r--r-- | src/citra_qt/configure_input.ui | 3 | ||||
-rw-r--r-- | src/core/CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/core/hle/kernel/resource_limit.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.cpp | 30 | ||||
-rw-r--r-- | src/core/hle/service/ac/ac.cpp | 181 | ||||
-rw-r--r-- | src/core/hle/service/ac/ac.h | 134 | ||||
-rw-r--r-- | src/core/hle/service/ac/ac_i.cpp | 39 | ||||
-rw-r--r-- | src/core/hle/service/ac/ac_i.h | 22 | ||||
-rw-r--r-- | src/core/hle/service/ac/ac_u.cpp | 39 | ||||
-rw-r--r-- | src/core/hle/service/ac/ac_u.h (renamed from src/core/hle/service/ac_u.h) | 1 | ||||
-rw-r--r-- | src/core/hle/service/ac_u.cpp | 291 | ||||
-rw-r--r-- | src/core/hle/service/service.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/y2r_u.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/svc.cpp | 26 |
16 files changed, 477 insertions, 353 deletions
diff --git a/src/citra_qt/configure_general.ui b/src/citra_qt/configure_general.ui index 342954e41..0f3352a1d 100644 --- a/src/citra_qt/configure_general.ui +++ b/src/citra_qt/configure_general.ui @@ -43,26 +43,26 @@ </layout> </widget> </item> - <item> - <widget class="QGroupBox" name="groupBox_2"> - <property name="title"> - <string>Performance</string> - </property> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <item> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <widget class="QCheckBox" name="toggle_cpu_jit"> - <property name="text"> - <string>Enable CPU JIT</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Performance</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="QCheckBox" name="toggle_cpu_jit"> + <property name="text"> + <string>Enable CPU JIT</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> <item> <widget class="QGroupBox" name="groupBox_4"> <property name="title"> diff --git a/src/citra_qt/configure_graphics.ui b/src/citra_qt/configure_graphics.ui index 62021fe22..a091f4c60 100644 --- a/src/citra_qt/configure_graphics.ui +++ b/src/citra_qt/configure_graphics.ui @@ -132,9 +132,9 @@ </property> <layout class="QHBoxLayout" name="horizontalLayout_3"> <item> - <layout class="QVBoxLayout" name="verticalLayout_2"> + <layout class="QVBoxLayout" name="verticalLayout_4"> <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> + <layout class="QHBoxLayout" name="horizontalLayout_4"> <item> <widget class="QLabel" name="label1"> <property name="text"> diff --git a/src/citra_qt/configure_input.ui b/src/citra_qt/configure_input.ui index a040d4df4..2760787e5 100644 --- a/src/citra_qt/configure_input.ui +++ b/src/citra_qt/configure_input.ui @@ -275,7 +275,6 @@ </layout> </item> </layout> - <zorder></zorder> </widget> </item> <item row="1" column="1"> @@ -521,7 +520,7 @@ <item row="1" column="1"> <layout class="QVBoxLayout" name="verticalLayout_28"> <item> - <widget class="QLabel" name="label_34"> + <widget class="QLabel" name="label_36"> <property name="text"> <string>Circle Mod:</string> </property> diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4c5b633e0..faad0a561 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -54,7 +54,9 @@ set(SRCS hle/kernel/thread.cpp hle/kernel/timer.cpp hle/kernel/vm_manager.cpp - hle/service/ac_u.cpp + hle/service/ac/ac.cpp + hle/service/ac/ac_i.cpp + hle/service/ac/ac_u.cpp hle/service/act/act.cpp hle/service/act/act_a.cpp hle/service/act/act_u.cpp @@ -229,7 +231,9 @@ set(HEADERS hle/kernel/timer.h hle/kernel/vm_manager.h hle/result.h - hle/service/ac_u.h + hle/service/ac/ac.h + hle/service/ac/ac_i.h + hle/service/ac/ac_u.h hle/service/act/act.h hle/service/act/act_a.h hle/service/act/act_u.h diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index 253ab7045..3f51bc5de 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -62,6 +62,8 @@ s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const { s32 ResourceLimit::GetMaxResourceValue(u32 resource) const { switch (resource) { + case PRIORITY: + return max_priority; case COMMIT: return max_commit; case THREAD: diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 8c6fbcd04..3b7555d87 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -353,14 +353,8 @@ static void ResetThreadContext(ARM_Interface::ThreadContext& context, u32 stack_ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, s32 priority, u32 arg, s32 processor_id, VAddr stack_top) { - if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) { - s32 new_priority = MathUtil::Clamp<s32>(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); - LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", name.c_str(), - priority, new_priority); - // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm - // validity of this - priority = new_priority; - } + ASSERT_MSG(priority >= THREADPRIO_HIGHEST && priority <= THREADPRIO_LOWEST, + "Invalid thread priority"); if (!Memory::IsValidVirtualAddress(entry_point)) { LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point); @@ -444,25 +438,9 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, return MakeResult<SharedPtr<Thread>>(std::move(thread)); } -// TODO(peachum): Remove this. Range checking should be done, and an appropriate error should be -// returned. -static void ClampPriority(const Thread* thread, s32* priority) { - if (*priority < THREADPRIO_HIGHEST || *priority > THREADPRIO_LOWEST) { - DEBUG_ASSERT_MSG( - false, "Application passed an out of range priority. An error should be returned."); - - s32 new_priority = MathUtil::Clamp<s32>(*priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); - LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", - thread->name.c_str(), *priority, new_priority); - // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm - // validity of this - *priority = new_priority; - } -} - void Thread::SetPriority(s32 priority) { - ClampPriority(this, &priority); - + ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST, + "Invalid priority value."); // If thread was ready, adjust queues if (status == THREADSTATUS_READY) ready_queue.move(this, current_priority, priority); diff --git a/src/core/hle/service/ac/ac.cpp b/src/core/hle/service/ac/ac.cpp new file mode 100644 index 000000000..aa270a2c3 --- /dev/null +++ b/src/core/hle/service/ac/ac.cpp @@ -0,0 +1,181 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <array> + +#include "common/logging/log.h" +#include "core/hle/kernel/event.h" +#include "core/hle/service/ac/ac.h" +#include "core/hle/service/ac/ac_i.h" +#include "core/hle/service/ac/ac_u.h" + +namespace Service { +namespace AC { + +struct ACConfig { + std::array<u8, 0x200> data; +}; + +static ACConfig default_config{}; + +static bool ac_connected = false; + +static Kernel::SharedPtr<Kernel::Event> close_event; +static Kernel::SharedPtr<Kernel::Event> connect_event; +static Kernel::SharedPtr<Kernel::Event> disconnect_event; + +void CreateDefaultConfig(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 ac_config_addr = cmd_buff[65]; + + ASSERT_MSG(cmd_buff[64] == (sizeof(ACConfig) << 14 | 2), + "Output buffer size not equal ACConfig size"); + + Memory::WriteBlock(ac_config_addr, &default_config, sizeof(ACConfig)); + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +void ConnectAsync(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + connect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); + if (connect_event) { + connect_event->name = "AC:connect_event"; + connect_event->Signal(); + ac_connected = true; + } + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +void GetConnectResult(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +void CloseAsync(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + if (ac_connected && disconnect_event) { + disconnect_event->Signal(); + } + + close_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); + if (close_event) { + close_event->name = "AC:close_event"; + close_event->Signal(); + } + + ac_connected = false; + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +void GetCloseResult(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +void GetWifiStatus(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + // TODO(purpasmart96): This function is only a stub, + // it returns a valid result without implementing full functionality. + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[2] = 0; // Connection type set to none + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +void GetInfraPriority(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[2] = 0; // Infra Priority, default 0 + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +void SetRequestEulaVersion(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + u32 major = cmd_buff[1] & 0xFF; + u32 minor = cmd_buff[2] & 0xFF; + + ASSERT_MSG(cmd_buff[3] == (sizeof(ACConfig) << 14 | 2), + "Input buffer size not equal ACConfig size"); + ASSERT_MSG(cmd_buff[64] == (sizeof(ACConfig) << 14 | 2), + "Output buffer size not equal ACConfig size"); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[2] = 0; // Infra Priority + + LOG_WARNING(Service_AC, "(STUBBED) called, major=%u, minor=%u", major, minor); +} + +void RegisterDisconnectEvent(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + disconnect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); + if (disconnect_event) { + disconnect_event->name = "AC:disconnect_event"; + } + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +void IsConnected(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[2] = ac_connected; + + LOG_WARNING(Service_AC, "(STUBBED) called"); +} + +void SetClientVersion(Interface* self) { + u32* cmd_buff = Kernel::GetCommandBuffer(); + + const u32 version = cmd_buff[1]; + self->SetVersion(version); + + LOG_WARNING(Service_AC, "(STUBBED) called, version: 0x%08X", version); + + cmd_buff[1] = RESULT_SUCCESS.raw; // No error +} + +void Init() { + AddService(new AC_I); + AddService(new AC_U); + + ac_connected = false; + + close_event = nullptr; + connect_event = nullptr; + disconnect_event = nullptr; +} + +void Shutdown() { + ac_connected = false; + + close_event = nullptr; + connect_event = nullptr; + disconnect_event = nullptr; +} + +} // namespace AC +} // namespace Service diff --git a/src/core/hle/service/ac/ac.h b/src/core/hle/service/ac/ac.h new file mode 100644 index 000000000..6185faf9b --- /dev/null +++ b/src/core/hle/service/ac/ac.h @@ -0,0 +1,134 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service { + +class Interface; + +namespace AC { + +/** + * AC::CreateDefaultConfig service function + * Inputs: + * 64 : ACConfig size << 14 | 2 + * 65 : pointer to ACConfig struct + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void CreateDefaultConfig(Interface* self); + +/** + * AC::ConnectAsync service function + * Inputs: + * 1 : ProcessId Header + * 3 : Copy Handle Header + * 4 : Connection Event handle + * 5 : ACConfig size << 14 | 2 + * 6 : pointer to ACConfig struct + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void ConnectAsync(Interface* self); + +/** + * AC::GetConnectResult service function + * Inputs: + * 1 : ProcessId Header + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void GetConnectResult(Interface* self); + +/** + * AC::CloseAsync service function + * Inputs: + * 1 : ProcessId Header + * 3 : Copy Handle Header + * 4 : Event handle, should be signaled when AC connection is closed + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void CloseAsync(Interface* self); + +/** + * AC::GetCloseResult service function + * Inputs: + * 1 : ProcessId Header + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void GetCloseResult(Interface* self); + +/** + * AC::GetWifiStatus service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Output connection type, 0 = none, 1 = Old3DS Internet, 2 = New3DS Internet. + */ +void GetWifiStatus(Interface* self); + +/** + * AC::GetInfraPriority service function + * Inputs: + * 1 : ACConfig size << 14 | 2 + * 2 : pointer to ACConfig struct + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Infra Priority + */ +void GetInfraPriority(Interface* self); + +/** + * AC::SetRequestEulaVersion service function + * Inputs: + * 1 : Eula Version major + * 2 : Eula Version minor + * 3 : ACConfig size << 14 | 2 + * 4 : Input pointer to ACConfig struct + * 64 : ACConfig size << 14 | 2 + * 65 : Output pointer to ACConfig struct + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Infra Priority + */ +void SetRequestEulaVersion(Interface* self); + +/** + * AC::RegisterDisconnectEvent service function + * Inputs: + * 1 : ProcessId Header + * 3 : Copy Handle Header + * 4 : Event handle, should be signaled when AC connection is closed + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void RegisterDisconnectEvent(Interface* self); + +/** + * AC::IsConnected service function + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : bool, is connected + */ +void IsConnected(Interface* self); + +/** + * AC::SetClientVersion service function + * Inputs: + * 1 : Used SDK Version + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void SetClientVersion(Interface* self); + +/// Initialize AC service +void Init(); + +/// Shutdown AC service +void Shutdown(); + +} // namespace AC +} // namespace Service diff --git a/src/core/hle/service/ac/ac_i.cpp b/src/core/hle/service/ac/ac_i.cpp new file mode 100644 index 000000000..b22fe3698 --- /dev/null +++ b/src/core/hle/service/ac/ac_i.cpp @@ -0,0 +1,39 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/ac/ac.h" +#include "core/hle/service/ac/ac_i.h" + +namespace Service { +namespace AC { + +const Interface::FunctionInfo FunctionTable[] = { + {0x00010000, CreateDefaultConfig, "CreateDefaultConfig"}, + {0x00040006, ConnectAsync, "ConnectAsync"}, + {0x00050002, GetConnectResult, "GetConnectResult"}, + {0x00070002, nullptr, "CancelConnectAsync"}, + {0x00080004, CloseAsync, "CloseAsync"}, + {0x00090002, GetCloseResult, "GetCloseResult"}, + {0x000A0000, nullptr, "GetLastErrorCode"}, + {0x000C0000, nullptr, "GetStatus"}, + {0x000D0000, GetWifiStatus, "GetWifiStatus"}, + {0x000E0042, nullptr, "GetCurrentAPInfo"}, + {0x00100042, nullptr, "GetCurrentNZoneInfo"}, + {0x00110042, nullptr, "GetNZoneApNumService"}, + {0x001D0042, nullptr, "ScanAPs"}, + {0x00240042, nullptr, "AddDenyApType"}, + {0x00270002, GetInfraPriority, "GetInfraPriority"}, + {0x002D0082, SetRequestEulaVersion, "SetRequestEulaVersion"}, + {0x00300004, RegisterDisconnectEvent, "RegisterDisconnectEvent"}, + {0x003C0042, nullptr, "GetAPSSIDList"}, + {0x003E0042, IsConnected, "IsConnected"}, + {0x00400042, SetClientVersion, "SetClientVersion"}, +}; + +AC_I::AC_I() { + Register(FunctionTable); +} + +} // namespace AC +} // namespace Service diff --git a/src/core/hle/service/ac/ac_i.h b/src/core/hle/service/ac/ac_i.h new file mode 100644 index 000000000..465bba59c --- /dev/null +++ b/src/core/hle/service/ac/ac_i.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace AC { + +class AC_I final : public Interface { +public: + AC_I(); + + std::string GetPortName() const override { + return "ac:i"; + } +}; + +} // namespace AC +} // namespace Service diff --git a/src/core/hle/service/ac/ac_u.cpp b/src/core/hle/service/ac/ac_u.cpp new file mode 100644 index 000000000..346671b4a --- /dev/null +++ b/src/core/hle/service/ac/ac_u.cpp @@ -0,0 +1,39 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/ac/ac.h" +#include "core/hle/service/ac/ac_u.h" + +namespace Service { +namespace AC { + +const Interface::FunctionInfo FunctionTable[] = { + {0x00010000, CreateDefaultConfig, "CreateDefaultConfig"}, + {0x00040006, ConnectAsync, "ConnectAsync"}, + {0x00050002, GetConnectResult, "GetConnectResult"}, + {0x00070002, nullptr, "CancelConnectAsync"}, + {0x00080004, CloseAsync, "CloseAsync"}, + {0x00090002, GetCloseResult, "GetCloseResult"}, + {0x000A0000, nullptr, "GetLastErrorCode"}, + {0x000C0000, nullptr, "GetStatus"}, + {0x000D0000, GetWifiStatus, "GetWifiStatus"}, + {0x000E0042, nullptr, "GetCurrentAPInfo"}, + {0x00100042, nullptr, "GetCurrentNZoneInfo"}, + {0x00110042, nullptr, "GetNZoneApNumService"}, + {0x001D0042, nullptr, "ScanAPs"}, + {0x00240042, nullptr, "AddDenyApType"}, + {0x00270002, GetInfraPriority, "GetInfraPriority"}, + {0x002D0082, SetRequestEulaVersion, "SetRequestEulaVersion"}, + {0x00300004, RegisterDisconnectEvent, "RegisterDisconnectEvent"}, + {0x003C0042, nullptr, "GetAPSSIDList"}, + {0x003E0042, IsConnected, "IsConnected"}, + {0x00400042, SetClientVersion, "SetClientVersion"}, +}; + +AC_U::AC_U() { + Register(FunctionTable); +} + +} // namespace AC +} // namespace Service diff --git a/src/core/hle/service/ac_u.h b/src/core/hle/service/ac/ac_u.h index 573c32d7e..f9d21e112 100644 --- a/src/core/hle/service/ac_u.h +++ b/src/core/hle/service/ac/ac_u.h @@ -12,7 +12,6 @@ namespace AC { class AC_U final : public Interface { public: AC_U(); - ~AC_U(); std::string GetPortName() const override { return "ac:u"; diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp deleted file mode 100644 index 36204db4d..000000000 --- a/src/core/hle/service/ac_u.cpp +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include <array> - -#include "common/logging/log.h" -#include "core/hle/kernel/event.h" -#include "core/hle/service/ac_u.h" - -namespace Service { -namespace AC { - -struct ACConfig { - std::array<u8, 0x200> data; -}; - -static ACConfig default_config{}; - -static bool ac_connected = false; - -static Kernel::SharedPtr<Kernel::Event> close_event; -static Kernel::SharedPtr<Kernel::Event> connect_event; -static Kernel::SharedPtr<Kernel::Event> disconnect_event; - -/** - * AC_U::CreateDefaultConfig service function - * Inputs: - * 64 : ACConfig size << 14 | 2 - * 65 : pointer to ACConfig struct - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void CreateDefaultConfig(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - u32 ac_config_addr = cmd_buff[65]; - - ASSERT_MSG(cmd_buff[64] == (sizeof(ACConfig) << 14 | 2), - "Output buffer size not equal ACConfig size"); - - Memory::WriteBlock(ac_config_addr, &default_config, sizeof(ACConfig)); - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - - LOG_WARNING(Service_AC, "(STUBBED) called"); -} - -/** - * AC_U::ConnectAsync service function - * Inputs: - * 1 : ProcessId Header - * 3 : Copy Handle Header - * 4 : Connection Event handle - * 5 : ACConfig size << 14 | 2 - * 6 : pointer to ACConfig struct - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void ConnectAsync(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - connect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); - if (connect_event) { - connect_event->name = "AC_U:connect_event"; - connect_event->Signal(); - ac_connected = true; - } - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - - LOG_WARNING(Service_AC, "(STUBBED) called"); -} - -/** - * AC_U::GetConnectResult service function - * Inputs: - * 1 : ProcessId Header - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void GetConnectResult(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - - LOG_WARNING(Service_AC, "(STUBBED) called"); -} - -/** - * AC_U::CloseAsync service function - * Inputs: - * 1 : ProcessId Header - * 3 : Copy Handle Header - * 4 : Event handle, should be signaled when AC connection is closed - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void CloseAsync(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - if (ac_connected && disconnect_event) { - disconnect_event->Signal(); - } - - close_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); - if (close_event) { - close_event->name = "AC_U:close_event"; - close_event->Signal(); - } - - ac_connected = false; - - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_AC, "(STUBBED) called"); -} - -/** - * AC_U::GetCloseResult service function - * Inputs: - * 1 : ProcessId Header - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void GetCloseResult(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - - LOG_WARNING(Service_AC, "(STUBBED) called"); -} - -/** - * AC_U::GetWifiStatus service function - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Output connection type, 0 = none, 1 = Old3DS Internet, 2 = New3DS Internet. - */ -static void GetWifiStatus(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - // TODO(purpasmart96): This function is only a stub, - // it returns a valid result without implementing full functionality. - - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = 0; // Connection type set to none - - LOG_WARNING(Service_AC, "(STUBBED) called"); -} - -/** - * AC_U::GetInfraPriority service function - * Inputs: - * 1 : ACConfig size << 14 | 2 - * 2 : pointer to ACConfig struct - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Infra Priority - */ -static void GetInfraPriority(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = 0; // Infra Priority, default 0 - - LOG_WARNING(Service_AC, "(STUBBED) called"); -} - -/** - * AC_U::SetRequestEulaVersion service function - * Inputs: - * 1 : Eula Version major - * 2 : Eula Version minor - * 3 : ACConfig size << 14 | 2 - * 4 : Input pointer to ACConfig struct - * 64 : ACConfig size << 14 | 2 - * 65 : Output pointer to ACConfig struct - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : Infra Priority - */ -static void SetRequestEulaVersion(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - u32 major = cmd_buff[1] & 0xFF; - u32 minor = cmd_buff[2] & 0xFF; - - ASSERT_MSG(cmd_buff[3] == (sizeof(ACConfig) << 14 | 2), - "Input buffer size not equal ACConfig size"); - ASSERT_MSG(cmd_buff[64] == (sizeof(ACConfig) << 14 | 2), - "Output buffer size not equal ACConfig size"); - - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = 0; // Infra Priority - - LOG_WARNING(Service_AC, "(STUBBED) called, major=%u, minor=%u", major, minor); -} - -/** - * AC_U::RegisterDisconnectEvent service function - * Inputs: - * 1 : ProcessId Header - * 3 : Copy Handle Header - * 4 : Event handle, should be signaled when AC connection is closed - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void RegisterDisconnectEvent(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - disconnect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); - if (disconnect_event) { - disconnect_event->name = "AC_U:disconnect_event"; - } - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - - LOG_WARNING(Service_AC, "(STUBBED) called"); -} - -/** - * AC_U::IsConnected service function - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - * 2 : bool, is connected - */ -static void IsConnected(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = ac_connected; - - LOG_WARNING(Service_AC, "(STUBBED) called"); -} - -/** - * AC_U::SetClientVersion service function - * Inputs: - * 1 : Used SDK Version - * Outputs: - * 1 : Result of function, 0 on success, otherwise error code - */ -static void SetClientVersion(Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); - - const u32 version = cmd_buff[1]; - self->SetVersion(version); - - LOG_WARNING(Service_AC, "(STUBBED) called, version: 0x%08X", version); - - cmd_buff[1] = RESULT_SUCCESS.raw; // No error -} - -const Interface::FunctionInfo FunctionTable[] = { - {0x00010000, CreateDefaultConfig, "CreateDefaultConfig"}, - {0x00040006, ConnectAsync, "ConnectAsync"}, - {0x00050002, GetConnectResult, "GetConnectResult"}, - {0x00070002, nullptr, "CancelConnectAsync"}, - {0x00080004, CloseAsync, "CloseAsync"}, - {0x00090002, GetCloseResult, "GetCloseResult"}, - {0x000A0000, nullptr, "GetLastErrorCode"}, - {0x000C0000, nullptr, "GetStatus"}, - {0x000D0000, GetWifiStatus, "GetWifiStatus"}, - {0x000E0042, nullptr, "GetCurrentAPInfo"}, - {0x00100042, nullptr, "GetCurrentNZoneInfo"}, - {0x00110042, nullptr, "GetNZoneApNumService"}, - {0x001D0042, nullptr, "ScanAPs"}, - {0x00240042, nullptr, "AddDenyApType"}, - {0x00270002, GetInfraPriority, "GetInfraPriority"}, - {0x002D0082, SetRequestEulaVersion, "SetRequestEulaVersion"}, - {0x00300004, RegisterDisconnectEvent, "RegisterDisconnectEvent"}, - {0x003C0042, nullptr, "GetAPSSIDList"}, - {0x003E0042, IsConnected, "IsConnected"}, - {0x00400042, SetClientVersion, "SetClientVersion"}, -}; - -AC_U::AC_U() { - Register(FunctionTable); - - ac_connected = false; - - close_event = nullptr; - connect_event = nullptr; - disconnect_event = nullptr; -} - -AC_U::~AC_U() { - close_event = nullptr; - connect_event = nullptr; - disconnect_event = nullptr; -} - -} // namespace AC -} // namespace Service diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index f3190e0fa..0672ac2e3 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -6,9 +6,8 @@ #include "common/logging/log.h" #include "common/string_util.h" - #include "core/hle/kernel/server_port.h" -#include "core/hle/service/ac_u.h" +#include "core/hle/service/ac/ac.h" #include "core/hle/service/act/act.h" #include "core/hle/service/am/am.h" #include "core/hle/service/apt/apt.h" @@ -138,6 +137,7 @@ void Init() { AddNamedPort(new ERR::ERR_F); FS::ArchiveInit(); + AC::Init(); ACT::Init(); AM::Init(); APT::Init(); @@ -158,7 +158,6 @@ void Init() { PTM::Init(); QTM::Init(); - AddService(new AC::AC_U); AddService(new CSND::CSND_SND); AddService(new DSP_DSP::Interface); AddService(new GSP::GSP_GPU); @@ -192,6 +191,7 @@ void Shutdown() { BOSS::Shutdown(); APT::Shutdown(); AM::Shutdown(); + AC::Shutdown(); FS::ArchiveShutdown(); g_srv_services.clear(); diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index a20194107..31bb466fc 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -531,7 +531,9 @@ static void GetStandardCoefficient(Interface* self) { LOG_DEBUG(Service_Y2R, "called standard_coefficient=%u ", index); } else { cmd_buff[0] = IPC::MakeHeader(0x21, 1, 0); - cmd_buff[1] = -1; // TODO(bunnei): Identify the correct error code for this + cmd_buff[1] = ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::CAM, + ErrorSummary::InvalidArgument, ErrorLevel::Usage) + .raw; LOG_ERROR(Service_Y2R, "called standard_coefficient=%u The argument is invalid!", index); } diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 2b242ff98..96db39ad9 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -532,16 +532,18 @@ static ResultCode CreateThread(Kernel::Handle* out_handle, s32 priority, u32 ent name = Common::StringFromFormat("unknown-%08x", entry_point); } - // TODO(bunnei): Implement resource limits to return an error code instead of the below assert. - // The error code should be: Description::NotAuthorized, Module::OS, Summary::WrongArgument, - // Level::Permanent - ASSERT_MSG(priority >= THREADPRIO_USERLAND_MAX, "Unexpected thread priority!"); - if (priority > THREADPRIO_LOWEST) { return ResultCode(ErrorDescription::OutOfRange, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); } + using Kernel::ResourceLimit; + Kernel::SharedPtr<ResourceLimit>& resource_limit = Kernel::g_current_process->resource_limit; + if (resource_limit->GetMaxResourceValue(Kernel::ResourceTypes::PRIORITY) > priority) { + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::OS, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); + } + switch (processor_id) { case THREADPROCESSORID_ALL: case THREADPROCESSORID_DEFAULT: @@ -598,10 +600,24 @@ static ResultCode GetThreadPriority(s32* priority, Kernel::Handle handle) { /// Sets the priority for the specified thread static ResultCode SetThreadPriority(Kernel::Handle handle, s32 priority) { + if (priority > THREADPRIO_LOWEST) { + return ResultCode(ErrorDescription::OutOfRange, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); + } + SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); if (thread == nullptr) return ERR_INVALID_HANDLE; + using Kernel::ResourceLimit; + // Note: The kernel uses the current process's resource limit instead of + // the one from the thread owner's resource limit. + Kernel::SharedPtr<ResourceLimit>& resource_limit = Kernel::g_current_process->resource_limit; + if (resource_limit->GetMaxResourceValue(Kernel::ResourceTypes::PRIORITY) > priority) { + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::OS, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); + } + thread->SetPriority(priority); thread->UpdatePriority(); |