diff options
Diffstat (limited to 'src/core/hle/service')
92 files changed, 3350 insertions, 386 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 0b158e015..6d15b46ed 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -10,6 +10,7 @@ #include "core/hle/service/acc/acc_su.h" #include "core/hle/service/acc/acc_u0.h" #include "core/hle/service/acc/acc_u1.h" +#include "core/settings.h" namespace Service::Account { @@ -31,13 +32,14 @@ struct ProfileBase { }; static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); +// TODO(ogniK): Generate a real user id based on username, md5(username) maybe? static constexpr u128 DEFAULT_USER_ID{1ull, 0ull}; class IProfile final : public ServiceFramework<IProfile> { public: explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) { static const FunctionInfo functions[] = { - {0, nullptr, "Get"}, + {0, &IProfile::Get, "Get"}, {1, &IProfile::GetBase, "GetBase"}, {10, nullptr, "GetImageSize"}, {11, nullptr, "LoadImage"}, @@ -46,14 +48,36 @@ public: } private: + void Get(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + ProfileBase profile_base{}; + profile_base.user_id = user_id; + if (Settings::values.username.size() > profile_base.username.size()) { + std::copy_n(Settings::values.username.begin(), profile_base.username.size(), + profile_base.username.begin()); + } else { + std::copy(Settings::values.username.begin(), Settings::values.username.end(), + profile_base.username.begin()); + } + + IPC::ResponseBuilder rb{ctx, 16}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(profile_base); + } + void GetBase(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); // TODO(Subv): Retrieve this information from somewhere. ProfileBase profile_base{}; profile_base.user_id = user_id; - profile_base.username = {'y', 'u', 'z', 'u'}; - + if (Settings::values.username.size() > profile_base.username.size()) { + std::copy_n(Settings::values.username.begin(), profile_base.username.size(), + profile_base.username.begin()); + } else { + std::copy(Settings::values.username.begin(), Settings::values.username.end(), + profile_base.username.begin()); + } IPC::ResponseBuilder rb{ctx, 16}; rb.Push(RESULT_SUCCESS); rb.PushRaw(profile_base); diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 97ef07bf9..9404d6b8c 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -11,6 +11,9 @@ #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_oe.h" +#include "core/hle/service/am/idle.h" +#include "core/hle/service/am/omm.h" +#include "core/hle/service/am/spsm.h" #include "core/hle/service/apm/apm.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/nvflinger/nvflinger.h" @@ -649,7 +652,8 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { // TODO(bunnei): This should be configurable IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US)); + rb.Push( + static_cast<u64>(Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index))); LOG_DEBUG(Service_AM, "called"); } @@ -689,6 +693,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager, std::shared_ptr<NVFlinger::NVFlinger> nvflinger) { std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager); std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager); + std::make_shared<IdleSys>()->InstallAsService(service_manager); + std::make_shared<OMM>()->InstallAsService(service_manager); + std::make_shared<SPSM>()->InstallAsService(service_manager); } IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") { diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/am/idle.cpp new file mode 100644 index 000000000..af46e9494 --- /dev/null +++ b/src/core/hle/service/am/idle.cpp @@ -0,0 +1,24 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/am/idle.h" + +namespace Service::AM { + +IdleSys::IdleSys() : ServiceFramework{"idle:sys"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetAutoPowerDownEvent"}, + {1, nullptr, "Unknown1"}, + {2, nullptr, "Unknown2"}, + {3, nullptr, "Unknown3"}, + {4, nullptr, "Unknown4"}, + {5, nullptr, "Unknown5"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::AM diff --git a/src/core/hle/service/am/idle.h b/src/core/hle/service/am/idle.h new file mode 100644 index 000000000..1eb68d2c9 --- /dev/null +++ b/src/core/hle/service/am/idle.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::AM { + +class IdleSys final : public ServiceFramework<IdleSys> { +public: + explicit IdleSys(); +}; + +} // namespace Service::AM diff --git a/src/core/hle/service/am/omm.cpp b/src/core/hle/service/am/omm.cpp new file mode 100644 index 000000000..447fe8669 --- /dev/null +++ b/src/core/hle/service/am/omm.cpp @@ -0,0 +1,42 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/am/omm.h" + +namespace Service::AM { + +OMM::OMM() : ServiceFramework{"omm"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetOperationMode"}, + {1, nullptr, "GetOperationModeChangeEvent"}, + {2, nullptr, "EnableAudioVisual"}, + {3, nullptr, "DisableAudioVisual"}, + {4, nullptr, "EnterSleepAndWait"}, + {5, nullptr, "GetCradleStatus"}, + {6, nullptr, "FadeInDisplay"}, + {7, nullptr, "FadeOutDisplay"}, + {8, nullptr, "Unknown1"}, + {9, nullptr, "Unknown2"}, + {10, nullptr, "Unknown3"}, + {11, nullptr, "Unknown4"}, + {12, nullptr, "Unknown5"}, + {13, nullptr, "Unknown6"}, + {14, nullptr, "Unknown7"}, + {15, nullptr, "Unknown8"}, + {16, nullptr, "Unknown9"}, + {17, nullptr, "Unknown10"}, + {18, nullptr, "Unknown11"}, + {19, nullptr, "Unknown12"}, + {20, nullptr, "Unknown13"}, + {21, nullptr, "Unknown14"}, + {22, nullptr, "Unknown15"}, + {23, nullptr, "Unknown16"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::AM diff --git a/src/core/hle/service/am/omm.h b/src/core/hle/service/am/omm.h new file mode 100644 index 000000000..49e5d331c --- /dev/null +++ b/src/core/hle/service/am/omm.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::AM { + +class OMM final : public ServiceFramework<OMM> { +public: + explicit OMM(); +}; + +} // namespace Service::AM diff --git a/src/core/hle/service/am/spsm.cpp b/src/core/hle/service/am/spsm.cpp new file mode 100644 index 000000000..a05d433d0 --- /dev/null +++ b/src/core/hle/service/am/spsm.cpp @@ -0,0 +1,30 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/am/spsm.h" + +namespace Service::AM { + +SPSM::SPSM() : ServiceFramework{"spsm"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetState"}, + {1, nullptr, "SleepSystemAndWaitAwake"}, + {2, nullptr, "Unknown1"}, + {3, nullptr, "Unknown2"}, + {4, nullptr, "GetNotificationMessageEventHandle"}, + {5, nullptr, "Unknown3"}, + {6, nullptr, "Unknown4"}, + {7, nullptr, "Unknown5"}, + {8, nullptr, "AnalyzePerformanceLogForLastSleepWakeSequence"}, + {9, nullptr, "ChangeHomeButtonLongPressingTime"}, + {10, nullptr, "Unknown6"}, + {11, nullptr, "Unknown7"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::AM diff --git a/src/core/hle/service/am/spsm.h b/src/core/hle/service/am/spsm.h new file mode 100644 index 000000000..57dde62e1 --- /dev/null +++ b/src/core/hle/service/am/spsm.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::AM { + +class SPSM final : public ServiceFramework<SPSM> { +public: + explicit SPSM(); +}; + +} // namespace Service::AM diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 7a185c6c8..4109cb7f7 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -13,6 +13,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) { auto module_ = std::make_shared<Module>(); std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager); std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager); + std::make_shared<APM_Sys>()->InstallAsService(service_manager); } } // namespace Service::APM diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index ce943d829..4cd8132f5 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp @@ -74,6 +74,31 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<ISession>(); + + LOG_DEBUG(Service_APM, "called"); +} + +APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RequestPerformanceMode"}, + {1, &APM_Sys::GetPerformanceEvent, "GetPerformanceEvent"}, + {2, nullptr, "GetThrottlingState"}, + {3, nullptr, "GetLastThrottlingState"}, + {4, nullptr, "ClearLastThrottlingState"}, + {5, nullptr, "LoadAndApplySettings"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<ISession>(); + + LOG_DEBUG(Service_APM, "called"); } } // namespace Service::APM diff --git a/src/core/hle/service/apm/interface.h b/src/core/hle/service/apm/interface.h index fa68c7d93..d14264ad7 100644 --- a/src/core/hle/service/apm/interface.h +++ b/src/core/hle/service/apm/interface.h @@ -19,4 +19,12 @@ private: std::shared_ptr<Module> apm; }; +class APM_Sys final : public ServiceFramework<APM_Sys> { +public: + explicit APM_Sys(); + +private: + void GetPerformanceEvent(Kernel::HLERequestContext& ctx); +}; + } // namespace Service::APM diff --git a/src/core/hle/service/arp/arp.cpp b/src/core/hle/service/arp/arp.cpp new file mode 100644 index 000000000..358ef2576 --- /dev/null +++ b/src/core/hle/service/arp/arp.cpp @@ -0,0 +1,75 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/arp/arp.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::ARP { + +class ARP_R final : public ServiceFramework<ARP_R> { +public: + explicit ARP_R() : ServiceFramework{"arp:r"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetApplicationLaunchProperty"}, + {1, nullptr, "GetApplicationLaunchPropertyWithApplicationId"}, + {2, nullptr, "GetApplicationControlProperty"}, + {3, nullptr, "GetApplicationControlPropertyWithApplicationId"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IRegistrar final : public ServiceFramework<IRegistrar> { +public: + explicit IRegistrar() : ServiceFramework{"IRegistrar"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Issue"}, + {1, nullptr, "SetApplicationLaunchProperty"}, + {2, nullptr, "SetApplicationControlProperty"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class ARP_W final : public ServiceFramework<ARP_W> { +public: + explicit ARP_W() : ServiceFramework{"arp:w"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, + {1, nullptr, "DeleteProperties"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void AcquireRegistrar(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IRegistrar>(); + + LOG_DEBUG(Service_ARP, "called"); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<ARP_R>()->InstallAsService(sm); + std::make_shared<ARP_W>()->InstallAsService(sm); +} + +} // namespace Service::ARP diff --git a/src/core/hle/service/arp/arp.h b/src/core/hle/service/arp/arp.h new file mode 100644 index 000000000..9d100187c --- /dev/null +++ b/src/core/hle/service/arp/arp.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::ARP { + +/// Registers all ARP services with the specified service manager. +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::ARP diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp new file mode 100644 index 000000000..37c3fdcac --- /dev/null +++ b/src/core/hle/service/audio/audctl.cpp @@ -0,0 +1,45 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/audio/audctl.h" + +namespace Service::Audio { + +AudCtl::AudCtl() : ServiceFramework{"audctl"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetTargetVolume"}, + {1, nullptr, "SetTargetVolume"}, + {2, nullptr, "GetTargetVolumeMin"}, + {3, nullptr, "GetTargetVolumeMax"}, + {4, nullptr, "IsTargetMute"}, + {5, nullptr, "SetTargetMute"}, + {6, nullptr, "IsTargetConnected"}, + {7, nullptr, "SetDefaultTarget"}, + {8, nullptr, "GetDefaultTarget"}, + {9, nullptr, "GetAudioOutputMode"}, + {10, nullptr, "SetAudioOutputMode"}, + {11, nullptr, "SetForceMutePolicy"}, + {12, nullptr, "GetForceMutePolicy"}, + {13, nullptr, "GetOutputModeSetting"}, + {14, nullptr, "SetOutputModeSetting"}, + {15, nullptr, "SetOutputTarget"}, + {16, nullptr, "SetInputTargetForceEnabled"}, + {17, nullptr, "SetHeadphoneOutputLevelMode"}, + {18, nullptr, "GetHeadphoneOutputLevelMode"}, + {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, + {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, + {21, nullptr, "GetAudioOutputTargetForPlayReport"}, + {22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"}, + {23, nullptr, "SetSystemOutputMasterVolume"}, + {24, nullptr, "GetSystemOutputMasterVolume"}, + {25, nullptr, "GetAudioVolumeDataForPlayReport"}, + {26, nullptr, "UpdateHeadphoneSettings"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h new file mode 100644 index 000000000..ed837bdf2 --- /dev/null +++ b/src/core/hle/service/audio/audctl.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class AudCtl final : public ServiceFramework<AudCtl> { +public: + explicit AudCtl(); +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/auddbg.cpp b/src/core/hle/service/audio/auddbg.cpp new file mode 100644 index 000000000..b08c21a20 --- /dev/null +++ b/src/core/hle/service/audio/auddbg.cpp @@ -0,0 +1,20 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/audio/auddbg.h" + +namespace Service::Audio { + +AudDbg::AudDbg(const char* name) : ServiceFramework{name} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RequestSuspendForDebug"}, + {1, nullptr, "RequestResumeForDebug"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/auddbg.h b/src/core/hle/service/audio/auddbg.h new file mode 100644 index 000000000..a2f540b75 --- /dev/null +++ b/src/core/hle/service/audio/auddbg.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class AudDbg final : public ServiceFramework<AudDbg> { +public: + explicit AudDbg(const char* name); +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audin_a.cpp b/src/core/hle/service/audio/audin_a.cpp new file mode 100644 index 000000000..a70d5bca4 --- /dev/null +++ b/src/core/hle/service/audio/audin_a.cpp @@ -0,0 +1,22 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/audio/audin_a.h" + +namespace Service::Audio { + +AudInA::AudInA() : ServiceFramework{"audin:a"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RequestSuspendAudioIns"}, + {1, nullptr, "RequestResumeAudioIns"}, + {2, nullptr, "GetAudioInsProcessMasterVolume"}, + {3, nullptr, "SetAudioInsProcessMasterVolume"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audin_a.h b/src/core/hle/service/audio/audin_a.h new file mode 100644 index 000000000..e4c75510f --- /dev/null +++ b/src/core/hle/service/audio/audin_a.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class AudInA final : public ServiceFramework<AudInA> { +public: + explicit AudInA(); +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index d231e91e1..6b5e15633 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp @@ -2,10 +2,16 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/hle/service/audio/audctl.h" +#include "core/hle/service/audio/auddbg.h" +#include "core/hle/service/audio/audin_a.h" #include "core/hle/service/audio/audin_u.h" #include "core/hle/service/audio/audio.h" +#include "core/hle/service/audio/audout_a.h" #include "core/hle/service/audio/audout_u.h" +#include "core/hle/service/audio/audrec_a.h" #include "core/hle/service/audio/audrec_u.h" +#include "core/hle/service/audio/audren_a.h" #include "core/hle/service/audio/audren_u.h" #include "core/hle/service/audio/codecctl.h" #include "core/hle/service/audio/hwopus.h" @@ -13,12 +19,22 @@ namespace Service::Audio { void InstallInterfaces(SM::ServiceManager& service_manager) { + std::make_shared<AudCtl>()->InstallAsService(service_manager); + std::make_shared<AudOutA>()->InstallAsService(service_manager); std::make_shared<AudOutU>()->InstallAsService(service_manager); + std::make_shared<AudInA>()->InstallAsService(service_manager); std::make_shared<AudInU>()->InstallAsService(service_manager); + std::make_shared<AudRecA>()->InstallAsService(service_manager); std::make_shared<AudRecU>()->InstallAsService(service_manager); + std::make_shared<AudRenA>()->InstallAsService(service_manager); std::make_shared<AudRenU>()->InstallAsService(service_manager); std::make_shared<CodecCtl>()->InstallAsService(service_manager); std::make_shared<HwOpus>()->InstallAsService(service_manager); + + std::make_shared<AudDbg>("audin:d")->InstallAsService(service_manager); + std::make_shared<AudDbg>("audout:d")->InstallAsService(service_manager); + std::make_shared<AudDbg>("audrec:d")->InstallAsService(service_manager); + std::make_shared<AudDbg>("audren:d")->InstallAsService(service_manager); } } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audout_a.cpp b/src/core/hle/service/audio/audout_a.cpp new file mode 100644 index 000000000..bf8d40157 --- /dev/null +++ b/src/core/hle/service/audio/audout_a.cpp @@ -0,0 +1,24 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/audio/audout_a.h" + +namespace Service::Audio { + +AudOutA::AudOutA() : ServiceFramework{"audout:a"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RequestSuspendAudioOuts"}, + {1, nullptr, "RequestResumeAudioOuts"}, + {2, nullptr, "GetAudioOutsProcessMasterVolume"}, + {3, nullptr, "SetAudioOutsProcessMasterVolume"}, + {4, nullptr, "GetAudioOutsProcessRecordVolume"}, + {5, nullptr, "SetAudioOutsProcessRecordVolume"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audout_a.h b/src/core/hle/service/audio/audout_a.h new file mode 100644 index 000000000..91a069152 --- /dev/null +++ b/src/core/hle/service/audio/audout_a.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class AudOutA final : public ServiceFramework<AudOutA> { +public: + explicit AudOutA(); +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 1dcd84d98..108a7c6eb 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -4,9 +4,10 @@ #include <array> #include <vector> + +#include "audio_core/codec.h" #include "common/logging/log.h" -#include "core/core_timing.h" -#include "core/core_timing_util.h" +#include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/hle_ipc.h" @@ -14,17 +15,21 @@ namespace Service::Audio { -/// Switch sample rate frequency -constexpr u32 sample_rate{48000}; -/// TODO(st4rk): dynamic number of channels, as I think Switch has support -/// to more audio channels (probably when Docked I guess) -constexpr u32 audio_channels{2}; -/// TODO(st4rk): find a proper value for the audio_ticks -constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 500)}; +namespace ErrCodes { +enum { + ErrorUnknown = 2, + BufferCountExceeded = 8, +}; +} + +constexpr std::array<char, 10> DefaultDevice{{"DeviceOut"}}; +constexpr int DefaultSampleRate{48000}; class IAudioOut final : public ServiceFramework<IAudioOut> { public: - IAudioOut() : ServiceFramework("IAudioOut"), audio_out_state(AudioState::Stopped) { + IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core) + : ServiceFramework("IAudioOut"), audio_params(audio_params), audio_core(audio_core) { + static const FunctionInfo functions[] = { {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, {1, &IAudioOut::StartAudioOut, "StartAudioOut"}, @@ -32,66 +37,65 @@ public: {3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"}, {4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"}, {5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"}, - {6, nullptr, "ContainsAudioOutBuffer"}, + {6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"}, {7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"}, {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"}, - {9, nullptr, "GetAudioOutBufferCount"}, + {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"}, {10, nullptr, "GetAudioOutPlayedSampleCount"}, {11, nullptr, "FlushAudioOutBuffers"}, }; RegisterHandlers(functions); // This is the event handle used to check if the audio buffer was released - buffer_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioOutBufferReleasedEvent"); - - // Register event callback to update the Audio Buffer - audio_event = CoreTiming::RegisterEvent( - "IAudioOut::UpdateAudioBuffersCallback", [this](u64 userdata, int cycles_late) { - UpdateAudioBuffersCallback(); - CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event); - }); - - // Start the audio event - CoreTiming::ScheduleEvent(audio_ticks, audio_event); - } + buffer_event = Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioOutBufferReleased"); - ~IAudioOut() { - CoreTiming::UnscheduleEvent(audio_event, 0); + stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count, + "IAudioOut", [=]() { buffer_event->Signal(); }); } private: + struct AudioBuffer { + u64_le next; + u64_le buffer; + u64_le buffer_capacity; + u64_le buffer_size; + u64_le offset; + }; + static_assert(sizeof(AudioBuffer) == 0x28, "AudioBuffer is an invalid size"); + void GetAudioOutState(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_Audio, "called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(static_cast<u32>(audio_out_state)); + rb.Push(static_cast<u32>(stream->IsPlaying() ? AudioState::Started : AudioState::Stopped)); } void StartAudioOut(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + LOG_DEBUG(Service_Audio, "called"); - // Start audio - audio_out_state = AudioState::Started; + if (stream->IsPlaying()) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::ErrorUnknown)); + return; + } + + audio_core.StartStream(stream); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void StopAudioOut(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); - - // Stop audio - audio_out_state = AudioState::Stopped; + LOG_DEBUG(Service_Audio, "called"); - queue_keys.clear(); + audio_core.StopStream(stream); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + LOG_DEBUG(Service_Audio, "called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); @@ -99,101 +103,107 @@ private: } void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + LOG_DEBUG(Service_Audio, "(STUBBED) called {}", ctx.Description()); IPC::RequestParser rp{ctx}; - const u64 key{rp.Pop<u64>()}; - queue_keys.insert(queue_keys.begin(), key); + const auto& input_buffer{ctx.ReadBuffer()}; + ASSERT_MSG(input_buffer.size() == sizeof(AudioBuffer), + "AudioBuffer input is an invalid size!"); + AudioBuffer audio_buffer{}; + std::memcpy(&audio_buffer, input_buffer.data(), sizeof(AudioBuffer)); + const u64 tag{rp.Pop<u64>()}; + + std::vector<s16> samples(audio_buffer.buffer_size / sizeof(s16)); + Memory::ReadBlock(audio_buffer.buffer, samples.data(), audio_buffer.buffer_size); + + if (!audio_core.QueueBuffer(stream, tag, std::move(samples))) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::BufferCountExceeded)); + } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void GetReleasedAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); - - // TODO(st4rk): This is how libtransistor currently implements the - // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address - // is used to know which buffer should be filled with data and send again to the service - // through AppendAudioOutBuffer. Check if this is the proper way to do it. - u64 key{0}; - - if (queue_keys.size()) { - key = queue_keys.back(); - queue_keys.pop_back(); - } + LOG_DEBUG(Service_Audio, "called {}", ctx.Description()); + IPC::RequestParser rp{ctx}; + const u64 max_count{ctx.GetWriteBufferSize() / sizeof(u64)}; + const auto released_buffers{audio_core.GetTagsAndReleaseBuffers(stream, max_count)}; - ctx.WriteBuffer(&key, sizeof(u64)); + std::vector<u64> tags{released_buffers}; + tags.resize(max_count); + ctx.WriteBuffer(tags); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - // TODO(st4rk): This might be the total of released buffers, needs to be verified on - // hardware - rb.Push<u32>(static_cast<u32>(queue_keys.size())); + rb.Push<u32>(static_cast<u32>(released_buffers.size())); } - void UpdateAudioBuffersCallback() { - if (audio_out_state != AudioState::Started) { - return; - } - - if (queue_keys.empty()) { - return; - } + void ContainsAudioOutBuffer(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + IPC::RequestParser rp{ctx}; + const u64 tag{rp.Pop<u64>()}; + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(stream->ContainsBuffer(tag)); + } - buffer_event->Signal(); + void GetAudioOutBufferCount(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_Audio, "called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(static_cast<u32>(stream->GetQueueSize())); } - enum class AudioState : u32 { - Started, - Stopped, - }; + AudioCore::AudioOut& audio_core; + AudioCore::StreamPtr stream; - /// This is used to trigger the audio event callback that is going to read the samples from the - /// audio_buffer list and enqueue the samples using the sink (audio_core). - CoreTiming::EventType* audio_event; + AudoutParams audio_params{}; /// This is the evend handle used to check if the audio buffer was released Kernel::SharedPtr<Kernel::Event> buffer_event; - - /// (st4rk): This is just a temporary workaround for the future implementation. Libtransistor - /// uses the key as an address in the App, so we need to return when the - /// GetReleasedAudioOutBuffer_1 is called, otherwise we'll run in problems, because - /// libtransistor uses the key returned as an pointer. - std::vector<u64> queue_keys; - - AudioState audio_out_state; }; void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + LOG_DEBUG(Service_Audio, "called"); IPC::RequestParser rp{ctx}; - constexpr std::array<char, 15> audio_interface{{"AudioInterface"}}; - ctx.WriteBuffer(audio_interface); + ctx.WriteBuffer(DefaultDevice); IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); rb.Push(RESULT_SUCCESS); - // TODO(st4rk): We're currently returning only one audio interface (stringlist size). However, - // it's highly possible to have more than one interface (despite that libtransistor requires - // only one). - rb.Push<u32>(1); + rb.Push<u32>(1); // Amount of audio devices } void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + LOG_DEBUG(Service_Audio, "called"); - if (!audio_out_interface) { - audio_out_interface = std::make_shared<IAudioOut>(); + ctx.WriteBuffer(DefaultDevice); + IPC::RequestParser rp{ctx}; + auto params{rp.PopRaw<AudoutParams>()}; + if (params.channel_count <= 2) { + // Mono does not exist for audout + params.channel_count = 2; + } else { + params.channel_count = 6; } + if (!params.sample_rate) { + params.sample_rate = DefaultSampleRate; + } + + // TODO(bunnei): Support more than one IAudioOut interface. When we add this, ListAudioOutsImpl + // will likely need to be updated as well. + ASSERT_MSG(!audio_out_interface, "Unimplemented"); + audio_out_interface = std::make_shared<IAudioOut>(params, *audio_core); IPC::ResponseBuilder rb{ctx, 6, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.Push<u32>(sample_rate); - rb.Push<u32>(audio_channels); - rb.Push<u32>(static_cast<u32>(PcmFormat::Int16)); - rb.Push<u32>(0); // This field is unknown + rb.Push<u32>(DefaultSampleRate); + rb.Push<u32>(params.channel_count); + rb.Push<u32>(static_cast<u32>(AudioCore::Codec::PcmFormat::Int16)); + rb.Push<u32>(static_cast<u32>(AudioState::Stopped)); rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface); } @@ -203,6 +213,7 @@ AudOutU::AudOutU() : ServiceFramework("audout:u") { {2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"}, {3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"}}; RegisterHandlers(functions); + audio_core = std::make_unique<AudioCore::AudioOut>(); } } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h index 847d86aa6..fd491f65d 100644 --- a/src/core/hle/service/audio/audout_u.h +++ b/src/core/hle/service/audio/audout_u.h @@ -4,6 +4,7 @@ #pragma once +#include "audio_core/audio_out.h" #include "core/hle/service/service.h" namespace Kernel { @@ -12,6 +13,18 @@ class HLERequestContext; namespace Service::Audio { +struct AudoutParams { + s32_le sample_rate; + u16_le channel_count; + INSERT_PADDING_BYTES(2); +}; +static_assert(sizeof(AudoutParams) == 0x8, "AudoutParams is an invalid size"); + +enum class AudioState : u32 { + Started, + Stopped, +}; + class IAudioOut; class AudOutU final : public ServiceFramework<AudOutU> { @@ -21,19 +34,10 @@ public: private: std::shared_ptr<IAudioOut> audio_out_interface; + std::unique_ptr<AudioCore::AudioOut> audio_core; void ListAudioOutsImpl(Kernel::HLERequestContext& ctx); void OpenAudioOutImpl(Kernel::HLERequestContext& ctx); - - enum class PcmFormat : u32 { - Invalid = 0, - Int8 = 1, - Int16 = 2, - Int24 = 3, - Int32 = 4, - PcmFloat = 5, - Adpcm = 6, - }; }; } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audrec_a.cpp b/src/core/hle/service/audio/audrec_a.cpp new file mode 100644 index 000000000..016eabf53 --- /dev/null +++ b/src/core/hle/service/audio/audrec_a.cpp @@ -0,0 +1,20 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/audio/audrec_a.h" + +namespace Service::Audio { + +AudRecA::AudRecA() : ServiceFramework{"audrec:a"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RequestSuspendFinalOutputRecorders"}, + {1, nullptr, "RequestResumeFinalOutputRecorders"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audrec_a.h b/src/core/hle/service/audio/audrec_a.h new file mode 100644 index 000000000..9685047f2 --- /dev/null +++ b/src/core/hle/service/audio/audrec_a.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class AudRecA final : public ServiceFramework<AudRecA> { +public: + explicit AudRecA(); +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audren_a.cpp b/src/core/hle/service/audio/audren_a.cpp new file mode 100644 index 000000000..616ff3dc4 --- /dev/null +++ b/src/core/hle/service/audio/audren_a.cpp @@ -0,0 +1,26 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/audio/audren_a.h" + +namespace Service::Audio { + +AudRenA::AudRenA() : ServiceFramework{"audren:a"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RequestSuspendAudioRenderers"}, + {1, nullptr, "RequestResumeAudioRenderers"}, + {2, nullptr, "GetAudioRenderersProcessMasterVolume"}, + {3, nullptr, "SetAudioRenderersProcessMasterVolume"}, + {4, nullptr, "RegisterAppletResourceUserId"}, + {5, nullptr, "UnregisterAppletResourceUserId"}, + {6, nullptr, "GetAudioRenderersProcessRecordVolume"}, + {7, nullptr, "SetAudioRenderersProcessRecordVolume"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audren_a.h b/src/core/hle/service/audio/audren_a.h new file mode 100644 index 000000000..5ecf2e184 --- /dev/null +++ b/src/core/hle/service/audio/audren_a.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Audio { + +class AudRenA final : public ServiceFramework<AudRenA> { +public: + explicit AudRenA(); +}; + +} // namespace Service::Audio diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 6aed9e2fa..f99304de5 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -15,13 +15,10 @@ namespace Service::Audio { -/// TODO(bunnei): Find a proper value for the audio_ticks -constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 200)}; - class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { public: - explicit IAudioRenderer(AudioRendererParameter audren_params) - : ServiceFramework("IAudioRenderer"), worker_params(audren_params) { + explicit IAudioRenderer(AudioCore::AudioRendererParameter audren_params) + : ServiceFramework("IAudioRenderer") { static const FunctionInfo functions[] = { {0, nullptr, "GetAudioRendererSampleRate"}, {1, nullptr, "GetAudioRendererSampleCount"}, @@ -39,21 +36,8 @@ public: RegisterHandlers(functions); system_event = - Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioRenderer:SystemEvent"); - - // Register event callback to update the Audio Buffer - audio_event = CoreTiming::RegisterEvent( - "IAudioRenderer::UpdateAudioCallback", [this](u64 userdata, int cycles_late) { - UpdateAudioCallback(); - CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event); - }); - - // Start the audio event - CoreTiming::ScheduleEvent(audio_ticks, audio_event); - voice_status_list.resize(worker_params.voice_count); - } - ~IAudioRenderer() { - CoreTiming::UnscheduleEvent(audio_event, 0); + Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent"); + renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event); } private: @@ -62,60 +46,9 @@ private: } void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { - UpdateDataHeader config{}; - auto buf = ctx.ReadBuffer(); - std::memcpy(&config, buf.data(), sizeof(UpdateDataHeader)); - u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4); - - std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count); - std::memcpy(mem_pool_info.data(), - buf.data() + sizeof(UpdateDataHeader) + config.behavior_size, - memory_pool_count * sizeof(MemoryPoolInfo)); - - std::vector<VoiceInfo> voice_info(worker_params.voice_count); - std::memcpy(voice_info.data(), - buf.data() + sizeof(UpdateDataHeader) + config.behavior_size + - config.memory_pools_size + config.voice_resource_size, - worker_params.voice_count * sizeof(VoiceInfo)); - - UpdateDataHeader response_data{worker_params}; - - ASSERT(ctx.GetWriteBufferSize() == response_data.total_size); - - std::vector<u8> output(response_data.total_size); - std::memcpy(output.data(), &response_data, sizeof(UpdateDataHeader)); - std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); - for (unsigned i = 0; i < memory_pool.size(); i++) { - if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestAttach) - memory_pool[i].state = MemoryPoolStates::Attached; - else if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestDetach) - memory_pool[i].state = MemoryPoolStates::Detached; - } - std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(), - response_data.memory_pools_size); - - for (unsigned i = 0; i < voice_info.size(); i++) { - if (voice_info[i].is_new) { - voice_status_list[i].played_sample_count = 0; - voice_status_list[i].wave_buffer_consumed = 0; - } else if (voice_info[i].play_state == (u8)PlayStates::Started) { - for (u32 buff_idx = 0; buff_idx < voice_info[i].wave_buffer_count; buff_idx++) { - voice_status_list[i].played_sample_count += - (voice_info[i].wave_buffer[buff_idx].end_sample_offset - - voice_info[i].wave_buffer[buff_idx].start_sample_offset) / - 2; - voice_status_list[i].wave_buffer_consumed++; - } - } - } - std::memcpy(output.data() + sizeof(UpdateDataHeader) + response_data.memory_pools_size, - voice_status_list.data(), response_data.voices_size); - - ctx.WriteBuffer(output); - + ctx.WriteBuffer(renderer->UpdateAudioRenderer(ctx.ReadBuffer())); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service_Audio, "(STUBBED) called"); } @@ -136,8 +69,6 @@ private: } void QuerySystemEvent(Kernel::HLERequestContext& ctx) { - // system_event->Signal(); - IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(system_event); @@ -145,131 +76,8 @@ private: LOG_WARNING(Service_Audio, "(STUBBED) called"); } - enum class MemoryPoolStates : u32 { // Should be LE - Invalid = 0x0, - Unknown = 0x1, - RequestDetach = 0x2, - Detached = 0x3, - RequestAttach = 0x4, - Attached = 0x5, - Released = 0x6, - }; - - enum class PlayStates : u8 { - Started = 0, - Stopped = 1, - }; - - struct MemoryPoolEntry { - MemoryPoolStates state; - u32_le unknown_4; - u32_le unknown_8; - u32_le unknown_c; - }; - static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size"); - - struct MemoryPoolInfo { - u64_le pool_address; - u64_le pool_size; - MemoryPoolStates pool_state; - INSERT_PADDING_WORDS(3); // Unknown - }; - static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size"); - - struct UpdateDataHeader { - UpdateDataHeader() {} - - explicit UpdateDataHeader(const AudioRendererParameter& config) { - revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision - behavior_size = 0xb0; - memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10; - voices_size = config.voice_count * 0x10; - voice_resource_size = 0x0; - effects_size = config.effect_count * 0x10; - mixes_size = 0x0; - sinks_size = config.sink_count * 0x20; - performance_manager_size = 0x10; - total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + - voices_size + effects_size + sinks_size + performance_manager_size; - } - - u32_le revision; - u32_le behavior_size; - u32_le memory_pools_size; - u32_le voices_size; - u32_le voice_resource_size; - u32_le effects_size; - u32_le mixes_size; - u32_le sinks_size; - u32_le performance_manager_size; - INSERT_PADDING_WORDS(6); - u32_le total_size; - }; - static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); - - struct BiquadFilter { - u8 enable; - INSERT_PADDING_BYTES(1); - s16_le numerator[3]; - s16_le denominator[2]; - }; - static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size"); - - struct WaveBuffer { - u64_le buffer_addr; - u64_le buffer_sz; - s32_le start_sample_offset; - s32_le end_sample_offset; - u8 loop; - u8 end_of_stream; - u8 sent_to_server; - INSERT_PADDING_BYTES(5); - u64 context_addr; - u64 context_sz; - INSERT_PADDING_BYTES(8); - }; - static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size"); - - struct VoiceInfo { - u32_le id; - u32_le node_id; - u8 is_new; - u8 is_in_use; - u8 play_state; - u8 sample_format; - u32_le sample_rate; - u32_le priority; - u32_le sorting_order; - u32_le channel_count; - float_le pitch; - float_le volume; - BiquadFilter biquad_filter[2]; - u32_le wave_buffer_count; - u16_le wave_buffer_head; - INSERT_PADDING_BYTES(6); - u64_le additional_params_addr; - u64_le additional_params_sz; - u32_le mix_id; - u32_le splitter_info_id; - WaveBuffer wave_buffer[4]; - u32_le voice_channel_resource_ids[6]; - INSERT_PADDING_BYTES(24); - }; - static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size"); - - struct VoiceOutStatus { - u64_le played_sample_count; - u32_le wave_buffer_consumed; - INSERT_PADDING_WORDS(1); - }; - static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size"); - - /// This is used to trigger the audio event callback. - CoreTiming::EventType* audio_event; - Kernel::SharedPtr<Kernel::Event> system_event; - AudioRendererParameter worker_params; - std::vector<VoiceOutStatus> voice_status_list; + std::unique_ptr<AudioCore::AudioRenderer> renderer; }; class IAudioDevice final : public ServiceFramework<IAudioDevice> { @@ -368,7 +176,7 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") { void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw<AudioRendererParameter>(); + auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -379,7 +187,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - auto params = rp.PopRaw<AudioRendererParameter>(); + auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); u64 buffer_sz = Common::AlignUp(4 * params.unknown_8, 0x40); buffer_sz += params.unknown_c * 1024; diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index b9b81db4f..14907f8ae 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h @@ -4,6 +4,7 @@ #pragma once +#include "audio_core/audio_renderer.h" #include "core/hle/service/service.h" namespace Kernel { @@ -12,24 +13,6 @@ class HLERequestContext; namespace Service::Audio { -struct AudioRendererParameter { - u32_le sample_rate; - u32_le sample_count; - u32_le unknown_8; - u32_le unknown_c; - u32_le voice_count; - u32_le sink_count; - u32_le effect_count; - u32_le unknown_1c; - u8 unknown_20; - INSERT_PADDING_BYTES(3); - u32_le splitter_count; - u32_le unknown_2c; - INSERT_PADDING_WORDS(1); - u32_le revision; -}; -static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size"); - class AudRenU final : public ServiceFramework<AudRenU> { public: explicit AudRenU(); diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index 844df382c..371cd4997 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cstring> +#include <opus.h> #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/hle_ipc.h" @@ -9,19 +11,142 @@ namespace Service::Audio { +struct OpusDeleter { + void operator()(void* ptr) const { + operator delete(ptr); + } +}; + +class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { +public: + IHardwareOpusDecoderManager(std::unique_ptr<OpusDecoder, OpusDeleter> decoder, u32 sample_rate, + u32 channel_count) + : ServiceFramework("IHardwareOpusDecoderManager"), decoder(std::move(decoder)), + sample_rate(sample_rate), channel_count(channel_count) { + static const FunctionInfo functions[] = { + {0, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"}, + {1, nullptr, "SetContext"}, + {2, nullptr, "DecodeInterleavedForMultiStream"}, + {3, nullptr, "SetContextForMultiStream"}, + {4, nullptr, "Unknown4"}, + {5, nullptr, "Unknown5"}, + {6, nullptr, "Unknown6"}, + {7, nullptr, "Unknown7"}, + }; + RegisterHandlers(functions); + } + +private: + void DecodeInterleaved(Kernel::HLERequestContext& ctx) { + u32 consumed = 0; + u32 sample_count = 0; + std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16)); + if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples)) { + IPC::ResponseBuilder rb{ctx, 2}; + // TODO(ogniK): Use correct error code + rb.Push(ResultCode(-1)); + return; + } + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(consumed); + rb.Push<u32>(sample_count); + ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16)); + } + + bool Decoder_DecodeInterleaved(u32& consumed, u32& sample_count, const std::vector<u8>& input, + std::vector<opus_int16>& output) { + size_t raw_output_sz = output.size() * sizeof(opus_int16); + if (sizeof(OpusHeader) > input.size()) + return false; + OpusHeader hdr{}; + std::memcpy(&hdr, input.data(), sizeof(OpusHeader)); + if (sizeof(OpusHeader) + static_cast<u32>(hdr.sz) > input.size()) { + return false; + } + auto frame = input.data() + sizeof(OpusHeader); + auto decoded_sample_count = opus_packet_get_nb_samples( + frame, static_cast<opus_int32>(input.size() - sizeof(OpusHeader)), + static_cast<opus_int32>(sample_rate)); + if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz) + return false; + auto out_sample_count = + opus_decode(decoder.get(), frame, hdr.sz, output.data(), + (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count)), 0); + if (out_sample_count < 0) + return false; + sample_count = out_sample_count; + consumed = static_cast<u32>(sizeof(OpusHeader) + hdr.sz); + return true; + } + + struct OpusHeader { + u32_be sz; // Needs to be BE for some odd reason + INSERT_PADDING_WORDS(1); + }; + static_assert(sizeof(OpusHeader) == 0x8, "OpusHeader is an invalid size"); + + std::unique_ptr<OpusDecoder, OpusDeleter> decoder; + u32 sample_rate; + u32 channel_count; +}; + +static size_t WorkerBufferSize(u32 channel_count) { + ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); + return opus_decoder_get_size(static_cast<int>(channel_count)); +} + void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_Audio, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + auto sample_rate = rp.Pop<u32>(); + auto channel_count = rp.Pop<u32>(); + ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 || + sample_rate == 12000 || sample_rate == 8000, + "Invalid sample rate"); + ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); + u32 worker_buffer_sz = static_cast<u32>(WorkerBufferSize(channel_count)); + LOG_DEBUG(Audio, "called worker_buffer_sz={}", worker_buffer_sz); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push<u32>(0x4000); + rb.Push<u32>(worker_buffer_sz); +} + +void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + auto sample_rate = rp.Pop<u32>(); + auto channel_count = rp.Pop<u32>(); + auto buffer_sz = rp.Pop<u32>(); + LOG_DEBUG(Audio, "called sample_rate={}, channel_count={}, buffer_size={}", sample_rate, + channel_count, buffer_sz); + ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 || + sample_rate == 12000 || sample_rate == 8000, + "Invalid sample rate"); + ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); + + size_t worker_sz = WorkerBufferSize(channel_count); + ASSERT_MSG(buffer_sz < worker_sz, "Worker buffer too large"); + std::unique_ptr<OpusDecoder, OpusDeleter> decoder{ + static_cast<OpusDecoder*>(operator new(worker_sz))}; + if (opus_decoder_init(decoder.get(), sample_rate, channel_count)) { + IPC::ResponseBuilder rb{ctx, 2}; + // TODO(ogniK): Use correct error code + rb.Push(ResultCode(-1)); + return; + } + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IHardwareOpusDecoderManager>(std::move(decoder), sample_rate, + channel_count); } HwOpus::HwOpus() : ServiceFramework("hwopus") { static const FunctionInfo functions[] = { - {0, nullptr, "Initialize"}, + {0, &HwOpus::OpenOpusDecoder, "OpenOpusDecoder"}, {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"}, - {2, nullptr, "InitializeMultiStream"}, - {3, nullptr, "GetWorkBufferSizeMultiStream"}, + {2, nullptr, "OpenOpusDecoderForMultiStream"}, + {3, nullptr, "GetWorkBufferSizeForMultiStream"}, }; RegisterHandlers(functions); } diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h index 090b8c825..5258d59f3 100644 --- a/src/core/hle/service/audio/hwopus.h +++ b/src/core/hle/service/audio/hwopus.h @@ -14,6 +14,7 @@ public: ~HwOpus() = default; private: + void OpenOpusDecoder(Kernel::HLERequestContext& ctx); void GetWorkBufferSize(Kernel::HLERequestContext& ctx); }; diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp new file mode 100644 index 000000000..1c1ecdb60 --- /dev/null +++ b/src/core/hle/service/bpc/bpc.cpp @@ -0,0 +1,57 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "core/hle/service/bpc/bpc.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::BPC { + +class BPC final : public ServiceFramework<BPC> { +public: + explicit BPC() : ServiceFramework{"bpc"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "ShutdownSystem"}, + {1, nullptr, "RebootSystem"}, + {2, nullptr, "GetWakeupReason"}, + {3, nullptr, "GetShutdownReason"}, + {4, nullptr, "GetAcOk"}, + {5, nullptr, "GetBoardPowerControlEvent"}, + {6, nullptr, "GetSleepButtonState"}, + {7, nullptr, "GetPowerEvent"}, + {8, nullptr, "Unknown1"}, + {9, nullptr, "Unknown2"}, + {10, nullptr, "Unknown3"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class BPC_R final : public ServiceFramework<BPC_R> { +public: + explicit BPC_R() : ServiceFramework{"bpc:r"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetExternalRtcValue"}, + {1, nullptr, "SetExternalRtcValue"}, + {2, nullptr, "ReadExternalRtcResetFlag"}, + {3, nullptr, "ClearExternalRtcResetFlag"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<BPC>()->InstallAsService(sm); + std::make_shared<BPC_R>()->InstallAsService(sm); +} + +} // namespace Service::BPC diff --git a/src/core/hle/service/bpc/bpc.h b/src/core/hle/service/bpc/bpc.h new file mode 100644 index 000000000..eaa37be8d --- /dev/null +++ b/src/core/hle/service/bpc/bpc.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::BPC { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::BPC diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp new file mode 100644 index 000000000..d0a15cc4c --- /dev/null +++ b/src/core/hle/service/btdrv/btdrv.cpp @@ -0,0 +1,72 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/btdrv/btdrv.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::BtDrv { + +class BtDrv final : public ServiceFramework<BtDrv> { +public: + explicit BtDrv() : ServiceFramework{"btdrv"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown"}, + {1, nullptr, "Init"}, + {2, nullptr, "Enable"}, + {3, nullptr, "Disable"}, + {4, nullptr, "CleanupAndShutdown"}, + {5, nullptr, "GetAdapterProperties"}, + {6, nullptr, "GetAdapterProperty"}, + {7, nullptr, "SetAdapterProperty"}, + {8, nullptr, "StartDiscovery"}, + {9, nullptr, "CancelDiscovery"}, + {10, nullptr, "CreateBond"}, + {11, nullptr, "RemoveBond"}, + {12, nullptr, "CancelBond"}, + {13, nullptr, "PinReply"}, + {14, nullptr, "SspReply"}, + {15, nullptr, "Unknown2"}, + {16, nullptr, "InitInterfaces"}, + {17, nullptr, "HidHostInterface_Connect"}, + {18, nullptr, "HidHostInterface_Disconnect"}, + {19, nullptr, "HidHostInterface_SendData"}, + {20, nullptr, "HidHostInterface_SendData2"}, + {21, nullptr, "HidHostInterface_SetReport"}, + {22, nullptr, "HidHostInterface_GetReport"}, + {23, nullptr, "HidHostInterface_WakeController"}, + {24, nullptr, "HidHostInterface_AddPairedDevice"}, + {25, nullptr, "HidHostInterface_GetPairedDevice"}, + {26, nullptr, "HidHostInterface_CleanupAndShutdown"}, + {27, nullptr, "Unknown3"}, + {28, nullptr, "ExtInterface_SetTSI"}, + {29, nullptr, "ExtInterface_SetBurstMode"}, + {30, nullptr, "ExtInterface_SetZeroRetran"}, + {31, nullptr, "ExtInterface_SetMcMode"}, + {32, nullptr, "ExtInterface_StartLlrMode"}, + {33, nullptr, "ExtInterface_ExitLlrMode"}, + {34, nullptr, "ExtInterface_SetRadio"}, + {35, nullptr, "ExtInterface_SetVisibility"}, + {36, nullptr, "Unknown4"}, + {37, nullptr, "Unknown5"}, + {38, nullptr, "HidHostInterface_GetLatestPlr"}, + {39, nullptr, "ExtInterface_GetPendingConnections"}, + {40, nullptr, "HidHostInterface_GetChannelMap"}, + {41, nullptr, "SetIsBluetoothBoostEnabled"}, + {42, nullptr, "GetIsBluetoothBoostEnabled"}, + {43, nullptr, "SetIsBluetoothAfhEnabled"}, + {44, nullptr, "GetIsBluetoothAfhEnabled"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<BtDrv>()->InstallAsService(sm); +} + +} // namespace Service::BtDrv diff --git a/src/core/hle/service/btdrv/btdrv.h b/src/core/hle/service/btdrv/btdrv.h new file mode 100644 index 000000000..164e56f43 --- /dev/null +++ b/src/core/hle/service/btdrv/btdrv.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::BtDrv { + +/// Registers all BtDrv services with the specified service manager. +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::BtDrv diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp new file mode 100644 index 000000000..b949bfabd --- /dev/null +++ b/src/core/hle/service/btm/btm.cpp @@ -0,0 +1,121 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/btm/btm.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::BTM { + +class BTM final : public ServiceFramework<BTM> { +public: + explicit BTM() : ServiceFramework{"btm"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "RegisterSystemEventForConnectedDeviceConditionImpl"}, + {3, nullptr, "Unknown3"}, + {4, nullptr, "Unknown4"}, + {5, nullptr, "Unknown5"}, + {6, nullptr, "Unknown6"}, + {7, nullptr, "Unknown7"}, + {8, nullptr, "RegisterSystemEventForRegisteredDeviceInfoImpl"}, + {9, nullptr, "Unknown8"}, + {10, nullptr, "Unknown9"}, + {11, nullptr, "Unknown10"}, + {12, nullptr, "Unknown11"}, + {13, nullptr, "Unknown12"}, + {14, nullptr, "EnableRadioImpl"}, + {15, nullptr, "DisableRadioImpl"}, + {16, nullptr, "Unknown13"}, + {17, nullptr, "Unknown14"}, + {18, nullptr, "Unknown15"}, + {19, nullptr, "Unknown16"}, + {20, nullptr, "Unknown17"}, + {21, nullptr, "Unknown18"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class BTM_DBG final : public ServiceFramework<BTM_DBG> { +public: + explicit BTM_DBG() : ServiceFramework{"btm:dbg"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RegisterSystemEventForDiscoveryImpl"}, + {1, nullptr, "Unknown1"}, + {2, nullptr, "Unknown2"}, + {3, nullptr, "Unknown3"}, + {4, nullptr, "Unknown4"}, + {5, nullptr, "Unknown5"}, + {6, nullptr, "Unknown6"}, + {7, nullptr, "Unknown7"}, + {8, nullptr, "Unknown8"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> { +public: + explicit IBtmSystemCore() : ServiceFramework{"IBtmSystemCore"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "StartGamepadPairingImpl"}, + {1, nullptr, "CancelGamepadPairingImpl"}, + {2, nullptr, "ClearGamepadPairingDatabaseImpl"}, + {3, nullptr, "GetPairedGamepadCountImpl"}, + {4, nullptr, "EnableRadioImpl"}, + {5, nullptr, "DisableRadioImpl"}, + {6, nullptr, "GetRadioOnOffImpl"}, + {7, nullptr, "AcquireRadioEventImpl"}, + {8, nullptr, "AcquireGamepadPairingEventImpl"}, + {9, nullptr, "IsGamepadPairingStartedImpl"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class BTM_SYS final : public ServiceFramework<BTM_SYS> { +public: + explicit BTM_SYS() : ServiceFramework{"btm:sys"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &BTM_SYS::GetCoreImpl, "GetCoreImpl"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void GetCoreImpl(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IBtmSystemCore>(); + + LOG_DEBUG(Service_BTM, "called"); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<BTM>()->InstallAsService(sm); + std::make_shared<BTM_DBG>()->InstallAsService(sm); + std::make_shared<BTM_SYS>()->InstallAsService(sm); +} + +} // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm.h b/src/core/hle/service/btm/btm.h new file mode 100644 index 000000000..e6425a7e3 --- /dev/null +++ b/src/core/hle/service/btm/btm.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::BTM { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::BTM diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp new file mode 100644 index 000000000..ae7b0720b --- /dev/null +++ b/src/core/hle/service/caps/caps.cpp @@ -0,0 +1,152 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "core/hle/service/caps/caps.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::Capture { + +class CAPS_A final : public ServiceFramework<CAPS_A> { +public: + explicit CAPS_A() : ServiceFramework{"caps:a"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "Unknown5"}, + {5, nullptr, "Unknown6"}, + {6, nullptr, "Unknown7"}, + {7, nullptr, "Unknown8"}, + {8, nullptr, "Unknown9"}, + {9, nullptr, "Unknown10"}, + {10, nullptr, "Unknown11"}, + {11, nullptr, "Unknown12"}, + {12, nullptr, "Unknown13"}, + {13, nullptr, "Unknown14"}, + {14, nullptr, "Unknown15"}, + {301, nullptr, "Unknown16"}, + {401, nullptr, "Unknown17"}, + {501, nullptr, "Unknown18"}, + {1001, nullptr, "Unknown19"}, + {1002, nullptr, "Unknown20"}, + {8001, nullptr, "Unknown21"}, + {8002, nullptr, "Unknown22"}, + {8011, nullptr, "Unknown23"}, + {8012, nullptr, "Unknown24"}, + {8021, nullptr, "Unknown25"}, + {10011, nullptr, "Unknown26"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class CAPS_C final : public ServiceFramework<CAPS_C> { +public: + explicit CAPS_C() : ServiceFramework{"caps:c"} { + // clang-format off + static const FunctionInfo functions[] = { + {2001, nullptr, "Unknown1"}, + {2002, nullptr, "Unknown2"}, + {2011, nullptr, "Unknown3"}, + {2012, nullptr, "Unknown4"}, + {2013, nullptr, "Unknown5"}, + {2014, nullptr, "Unknown6"}, + {2101, nullptr, "Unknown7"}, + {2102, nullptr, "Unknown8"}, + {2201, nullptr, "Unknown9"}, + {2301, nullptr, "Unknown10"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class CAPS_SC final : public ServiceFramework<CAPS_SC> { +public: + explicit CAPS_SC() : ServiceFramework{"caps:sc"} { + // clang-format off + static const FunctionInfo functions[] = { + {1, nullptr, "Unknown1"}, + {2, nullptr, "Unknown2"}, + {1001, nullptr, "Unknown3"}, + {1002, nullptr, "Unknown4"}, + {1003, nullptr, "Unknown5"}, + {1011, nullptr, "Unknown6"}, + {1012, nullptr, "Unknown7"}, + {1201, nullptr, "Unknown8"}, + {1202, nullptr, "Unknown9"}, + {1203, nullptr, "Unknown10"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class CAPS_SS final : public ServiceFramework<CAPS_SS> { +public: + explicit CAPS_SS() : ServiceFramework{"caps:ss"} { + // clang-format off + static const FunctionInfo functions[] = { + {201, nullptr, "Unknown1"}, + {202, nullptr, "Unknown2"}, + {203, nullptr, "Unknown3"}, + {204, nullptr, "Unknown4"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class CAPS_SU final : public ServiceFramework<CAPS_SU> { +public: + explicit CAPS_SU() : ServiceFramework{"caps:su"} { + // clang-format off + static const FunctionInfo functions[] = { + {201, nullptr, "SaveScreenShot"}, + {203, nullptr, "SaveScreenShotEx0"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class CAPS_U final : public ServiceFramework<CAPS_U> { +public: + explicit CAPS_U() : ServiceFramework{"caps:u"} { + // clang-format off + static const FunctionInfo functions[] = { + {102, nullptr, "GetAlbumFileListByAruid"}, + {103, nullptr, "DeleteAlbumFileByAruid"}, + {104, nullptr, "GetAlbumFileSizeByAruid"}, + {110, nullptr, "LoadAlbumScreenShotImageByAruid"}, + {120, nullptr, "LoadAlbumScreenShotThumbnailImageByAruid"}, + {60002, nullptr, "OpenAccessorSessionForApplication"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<CAPS_A>()->InstallAsService(sm); + std::make_shared<CAPS_C>()->InstallAsService(sm); + std::make_shared<CAPS_SC>()->InstallAsService(sm); + std::make_shared<CAPS_SS>()->InstallAsService(sm); + std::make_shared<CAPS_SU>()->InstallAsService(sm); + std::make_shared<CAPS_U>()->InstallAsService(sm); +} + +} // namespace Service::Capture diff --git a/src/core/hle/service/caps/caps.h b/src/core/hle/service/caps/caps.h new file mode 100644 index 000000000..471185dfa --- /dev/null +++ b/src/core/hle/service/caps/caps.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::Capture { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::Capture diff --git a/src/core/hle/service/fgm/fgm.cpp b/src/core/hle/service/fgm/fgm.cpp new file mode 100644 index 000000000..566fbf924 --- /dev/null +++ b/src/core/hle/service/fgm/fgm.cpp @@ -0,0 +1,75 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/fgm/fgm.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::FGM { + +class IRequest final : public ServiceFramework<IRequest> { +public: + explicit IRequest() : ServiceFramework{"IRequest"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {1, nullptr, "Set"}, + {2, nullptr, "Get"}, + {3, nullptr, "Cancel"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class FGM final : public ServiceFramework<FGM> { +public: + explicit FGM(const char* name) : ServiceFramework{name} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &FGM::Initialize, "Initialize"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void Initialize(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IRequest>(); + + LOG_DEBUG(Service_FGM, "called"); + } +}; + +class FGM_DBG final : public ServiceFramework<FGM_DBG> { +public: + explicit FGM_DBG() : ServiceFramework{"fgm:dbg"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {1, nullptr, "Read"}, + {2, nullptr, "Cancel"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<FGM>("fgm")->InstallAsService(sm); + std::make_shared<FGM>("fgm:0")->InstallAsService(sm); + std::make_shared<FGM>("fgm:9")->InstallAsService(sm); + std::make_shared<FGM_DBG>()->InstallAsService(sm); +} + +} // namespace Service::FGM diff --git a/src/core/hle/service/fgm/fgm.h b/src/core/hle/service/fgm/fgm.h new file mode 100644 index 000000000..e59691264 --- /dev/null +++ b/src/core/hle/service/fgm/fgm.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::FGM { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::FGM diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index fdd2fda18..e17d637e4 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -14,6 +14,8 @@ #include "core/file_sys/vfs_offset.h" #include "core/file_sys/vfs_real.h" #include "core/hle/service/filesystem/filesystem.h" +#include "core/hle/service/filesystem/fsp_ldr.h" +#include "core/hle/service/filesystem/fsp_pr.h" #include "core/hle/service/filesystem/fsp_srv.h" namespace Service::FileSystem { @@ -298,6 +300,8 @@ void RegisterFileSystems() { void InstallInterfaces(SM::ServiceManager& service_manager) { RegisterFileSystems(); + std::make_shared<FSP_LDR>()->InstallAsService(service_manager); + std::make_shared<FSP_PR>()->InstallAsService(service_manager); std::make_shared<FSP_SRV>()->InstallAsService(service_manager); } diff --git a/src/core/hle/service/filesystem/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp_ldr.cpp new file mode 100644 index 000000000..0ab9c2606 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp_ldr.cpp @@ -0,0 +1,22 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/filesystem/fsp_ldr.h" +#include "core/hle/service/service.h" + +namespace Service::FileSystem { + +FSP_LDR::FSP_LDR() : ServiceFramework{"fsp:ldr"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "OpenCodeFileSystem"}, + {1, nullptr, "IsArchivedProgram"}, + {2, nullptr, "SetCurrentProcess"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_ldr.h b/src/core/hle/service/filesystem/fsp_ldr.h new file mode 100644 index 000000000..fa8e11b4c --- /dev/null +++ b/src/core/hle/service/filesystem/fsp_ldr.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::FileSystem { + +class FSP_LDR final : public ServiceFramework<FSP_LDR> { +public: + explicit FSP_LDR(); +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp_pr.cpp new file mode 100644 index 000000000..32b0ae454 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp_pr.cpp @@ -0,0 +1,23 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/filesystem/fsp_pr.h" +#include "core/hle/service/service.h" + +namespace Service::FileSystem { + +FSP_PR::FSP_PR() : ServiceFramework{"fsp:pr"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RegisterProgram"}, + {1, nullptr, "UnregisterProgram"}, + {2, nullptr, "SetCurrentProcess"}, + {256, nullptr, "SetEnabledProgramVerification"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_pr.h b/src/core/hle/service/filesystem/fsp_pr.h new file mode 100644 index 000000000..62edcd08a --- /dev/null +++ b/src/core/hle/service/filesystem/fsp_pr.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::FileSystem { + +class FSP_PR final : public ServiceFramework<FSP_PR> { +public: + explicit FSP_PR(); +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index e4619a547..8f0262e34 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -326,7 +326,7 @@ public: {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"}, {80, nullptr, "GetGyroscopeZeroDriftMode"}, {81, nullptr, "ResetGyroscopeZeroDriftMode"}, - {82, nullptr, "IsSixAxisSensorAtRest"}, + {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"}, {91, nullptr, "ActivateGesture"}, {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"}, {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"}, @@ -337,13 +337,14 @@ public: "AcquireNpadStyleSetUpdateEventHandle"}, {107, nullptr, "DisconnectNpad"}, {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"}, + {109, nullptr, "ActivateNpadWithRevision"}, {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, - {125, nullptr, "MergeSingleJoyAsDualJoy"}, + {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, {126, nullptr, "StartLrAssignmentMode"}, {127, nullptr, "StopLrAssignmentMode"}, {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, @@ -455,6 +456,14 @@ private: LOG_WARNING(Service_HID, "(STUBBED) called"); } + void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + // TODO (Hexagon12): Properly implement reading gyroscope values from controllers. + rb.Push(true); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -530,6 +539,12 @@ private: LOG_WARNING(Service_HID, "(STUBBED) called"); } + void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp new file mode 100644 index 000000000..8fc8b1057 --- /dev/null +++ b/src/core/hle/service/lbl/lbl.cpp @@ -0,0 +1,90 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/lbl/lbl.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::LBL { + +class LBL final : public ServiceFramework<LBL> { +public: + explicit LBL() : ServiceFramework{"lbl"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "Unknown5"}, + {5, nullptr, "Unknown6"}, + {6, nullptr, "TurnOffBacklight"}, + {7, nullptr, "TurnOnBacklight"}, + {8, nullptr, "GetBacklightStatus"}, + {9, nullptr, "Unknown7"}, + {10, nullptr, "Unknown8"}, + {11, nullptr, "Unknown9"}, + {12, nullptr, "Unknown10"}, + {13, nullptr, "Unknown11"}, + {14, nullptr, "Unknown12"}, + {15, nullptr, "Unknown13"}, + {16, nullptr, "ReadRawLightSensor"}, + {17, nullptr, "Unknown14"}, + {18, nullptr, "Unknown15"}, + {19, nullptr, "Unknown16"}, + {20, nullptr, "Unknown17"}, + {21, nullptr, "Unknown18"}, + {22, nullptr, "Unknown19"}, + {23, nullptr, "Unknown20"}, + {24, nullptr, "Unknown21"}, + {25, nullptr, "Unknown22"}, + {26, &LBL::EnableVrMode, "EnableVrMode"}, + {27, &LBL::DisableVrMode, "DisableVrMode"}, + {28, &LBL::GetVrMode, "GetVrMode"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void EnableVrMode(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + + vr_mode_enabled = true; + + LOG_DEBUG(Service_LBL, "called"); + } + + void DisableVrMode(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + + vr_mode_enabled = false; + + LOG_DEBUG(Service_LBL, "called"); + } + + void GetVrMode(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(vr_mode_enabled); + + LOG_DEBUG(Service_LBL, "called"); + } + + bool vr_mode_enabled = false; +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<LBL>()->InstallAsService(sm); +} + +} // namespace Service::LBL diff --git a/src/core/hle/service/lbl/lbl.h b/src/core/hle/service/lbl/lbl.h new file mode 100644 index 000000000..bf6f400f8 --- /dev/null +++ b/src/core/hle/service/lbl/lbl.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::LBL { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::LBL diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index b497376d7..2e99ddf51 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -13,11 +13,11 @@ namespace Service::LM { -class Logger final : public ServiceFramework<Logger> { +class ILogger final : public ServiceFramework<ILogger> { public: - Logger() : ServiceFramework("Logger") { + ILogger() : ServiceFramework("ILogger") { static const FunctionInfo functions[] = { - {0x00000000, &Logger::Initialize, "Initialize"}, + {0x00000000, &ILogger::Initialize, "Initialize"}, {0x00000001, nullptr, "SetDestination"}, }; RegisterHandlers(functions); @@ -182,7 +182,7 @@ public: void OpenLogger(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<Logger>(); + rb.PushIpcInterface<ILogger>(); LOG_DEBUG(Service_LM, "called"); } diff --git a/src/core/hle/service/mig/mig.cpp b/src/core/hle/service/mig/mig.cpp new file mode 100644 index 000000000..d16367f2c --- /dev/null +++ b/src/core/hle/service/mig/mig.cpp @@ -0,0 +1,34 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "core/hle/service/mig/mig.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::Migration { + +class MIG_USR final : public ServiceFramework<MIG_USR> { +public: + explicit MIG_USR() : ServiceFramework{"mig:usr"} { + // clang-format off + static const FunctionInfo functions[] = { + {10, nullptr, "TryGetLastMigrationInfo"}, + {100, nullptr, "CreateServer"}, + {101, nullptr, "ResumeServer"}, + {200, nullptr, "CreateClient"}, + {201, nullptr, "ResumeClient"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<MIG_USR>()->InstallAsService(sm); +} + +} // namespace Service::Migration diff --git a/src/core/hle/service/mig/mig.h b/src/core/hle/service/mig/mig.h new file mode 100644 index 000000000..288c1c1b3 --- /dev/null +++ b/src/core/hle/service/mig/mig.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::Migration { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::Migration diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp new file mode 100644 index 000000000..a6197124a --- /dev/null +++ b/src/core/hle/service/mii/mii.cpp @@ -0,0 +1,107 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/mii/mii.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::Mii { + +class IDatabaseService final : public ServiceFramework<IDatabaseService> { +public: + explicit IDatabaseService() : ServiceFramework{"IDatabaseService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "IsUpdated"}, + {1, nullptr, "IsFullDatabase"}, + {2, nullptr, "GetCount"}, + {3, nullptr, "Get"}, + {4, nullptr, "Get1"}, + {5, nullptr, "UpdateLatest"}, + {6, nullptr, "BuildRandom"}, + {7, nullptr, "BuildDefault"}, + {8, nullptr, "Get2"}, + {9, nullptr, "Get3"}, + {10, nullptr, "UpdateLatest1"}, + {11, nullptr, "FindIndex"}, + {12, nullptr, "Move"}, + {13, nullptr, "AddOrReplace"}, + {14, nullptr, "Delete"}, + {15, nullptr, "DestroyFile"}, + {16, nullptr, "DeleteFile"}, + {17, nullptr, "Format"}, + {18, nullptr, "Import"}, + {19, nullptr, "Export"}, + {20, nullptr, "IsBrokenDatabaseWithClearFlag"}, + {21, nullptr, "GetIndex"}, + {22, nullptr, "SetInterfaceVersion"}, + {23, nullptr, "Convert"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class MiiDBModule final : public ServiceFramework<MiiDBModule> { +public: + explicit MiiDBModule(const char* name) : ServiceFramework{name} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void GetDatabaseService(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IDatabaseService>(); + + LOG_DEBUG(Service_Mii, "called"); + } +}; + +class MiiImg final : public ServiceFramework<MiiImg> { +public: + explicit MiiImg() : ServiceFramework{"miiimg"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {10, nullptr, "Reload"}, + {11, nullptr, "GetCount"}, + {12, nullptr, "IsEmpty"}, + {13, nullptr, "IsFull"}, + {14, nullptr, "GetAttribute"}, + {15, nullptr, "LoadImage"}, + {16, nullptr, "AddOrUpdateImage"}, + {17, nullptr, "DeleteImages"}, + {100, nullptr, "DeleteFile"}, + {101, nullptr, "DestroyFile"}, + {102, nullptr, "ImportFile"}, + {103, nullptr, "ExportFile"}, + {104, nullptr, "ForceInitialize"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<MiiDBModule>("mii:e")->InstallAsService(sm); + std::make_shared<MiiDBModule>("mii:u")->InstallAsService(sm); + + std::make_shared<MiiImg>()->InstallAsService(sm); +} + +} // namespace Service::Mii diff --git a/src/core/hle/service/mii/mii.h b/src/core/hle/service/mii/mii.h new file mode 100644 index 000000000..7ce9be50e --- /dev/null +++ b/src/core/hle/service/mii/mii.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::Mii { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::Mii diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp new file mode 100644 index 000000000..0297edca0 --- /dev/null +++ b/src/core/hle/service/ncm/ncm.cpp @@ -0,0 +1,59 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "core/hle/service/ncm/ncm.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::NCM { + +class LocationResolver final : public ServiceFramework<LocationResolver> { +public: + explicit LocationResolver() : ServiceFramework{"lr"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "OpenLocationResolver"}, + {1, nullptr, "OpenRegisteredLocationResolver"}, + {2, nullptr, "RefreshLocationResolver"}, + {3, nullptr, "OpenAddOnContentLocationResolver"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class NCM final : public ServiceFramework<NCM> { +public: + explicit NCM() : ServiceFramework{"ncm"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "CreateContentStorage"}, + {1, nullptr, "CreateContentMetaDatabase"}, + {2, nullptr, "VerifyContentStorage"}, + {3, nullptr, "VerifyContentMetaDatabase"}, + {4, nullptr, "OpenContentStorage"}, + {5, nullptr, "OpenContentMetaDatabase"}, + {6, nullptr, "CloseContentStorageForcibly"}, + {7, nullptr, "CloseContentMetaDatabaseForcibly"}, + {8, nullptr, "CleanupContentMetaDatabase"}, + {9, nullptr, "OpenContentStorage2"}, + {10, nullptr, "CloseContentStorage"}, + {11, nullptr, "OpenContentMetaDatabase2"}, + {12, nullptr, "CloseContentMetaDatabase"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<LocationResolver>()->InstallAsService(sm); + std::make_shared<NCM>()->InstallAsService(sm); +} + +} // namespace Service::NCM diff --git a/src/core/hle/service/ncm/ncm.h b/src/core/hle/service/ncm/ncm.h new file mode 100644 index 000000000..7bc8518a6 --- /dev/null +++ b/src/core/hle/service/ncm/ncm.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::NCM { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::NCM diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp new file mode 100644 index 000000000..8fec97db8 --- /dev/null +++ b/src/core/hle/service/nfc/nfc.cpp @@ -0,0 +1,222 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/nfc/nfc.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::NFC { + +class IAm final : public ServiceFramework<IAm> { +public: + explicit IAm() : ServiceFramework{"IAm"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {1, nullptr, "Finalize"}, + {2, nullptr, "NotifyForegroundApplet"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class NFC_AM final : public ServiceFramework<NFC_AM> { +public: + explicit NFC_AM() : ServiceFramework{"nfc:am"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &NFC_AM::CreateAmInterface, "CreateAmInterface"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void CreateAmInterface(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IAm>(); + + LOG_DEBUG(Service_NFC, "called"); + } +}; + +class MFIUser final : public ServiceFramework<MFIUser> { +public: + explicit MFIUser() : ServiceFramework{"IUser"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {1, nullptr, "Finalize"}, + {2, nullptr, "ListDevices"}, + {3, nullptr, "StartDetection"}, + {4, nullptr, "StopDetection"}, + {5, nullptr, "Read"}, + {6, nullptr, "Write"}, + {7, nullptr, "GetTagInfo"}, + {8, nullptr, "GetActivateEventHandle"}, + {9, nullptr, "GetDeactivateEventHandle"}, + {10, nullptr, "GetState"}, + {11, nullptr, "GetDeviceState"}, + {12, nullptr, "GetNpadId"}, + {13, nullptr, "GetAvailabilityChangeEventHandle"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class NFC_MF_U final : public ServiceFramework<NFC_MF_U> { +public: + explicit NFC_MF_U() : ServiceFramework{"nfc:mf:u"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &NFC_MF_U::CreateUserInterface, "CreateUserInterface"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void CreateUserInterface(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<MFIUser>(); + + LOG_DEBUG(Service_NFC, "called"); + } +}; + +class IUser final : public ServiceFramework<IUser> { +public: + explicit IUser() : ServiceFramework{"IUser"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {1, nullptr, "Finalize"}, + {2, nullptr, "GetState"}, + {3, nullptr, "IsNfcEnabled"}, + {400, nullptr, "Initialize"}, + {401, nullptr, "Finalize"}, + {402, nullptr, "GetState"}, + {403, nullptr, "IsNfcEnabled"}, + {404, nullptr, "ListDevices"}, + {405, nullptr, "GetDeviceState"}, + {406, nullptr, "GetNpadId"}, + {407, nullptr, "AttachAvailabilityChangeEvent"}, + {408, nullptr, "StartDetection"}, + {409, nullptr, "StopDetection"}, + {410, nullptr, "GetTagInfo"}, + {411, nullptr, "AttachActivateEvent"}, + {412, nullptr, "AttachDeactivateEvent"}, + {1000, nullptr, "ReadMifare"}, + {1001, nullptr, "WriteMifare"}, + {1300, nullptr, "SendCommandByPassThrough"}, + {1301, nullptr, "KeepPassThroughSession"}, + {1302, nullptr, "ReleasePassThroughSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class NFC_U final : public ServiceFramework<NFC_U> { +public: + explicit NFC_U() : ServiceFramework{"nfc:u"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &NFC_U::CreateUserInterface, "CreateUserInterface"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void CreateUserInterface(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IUser>(); + + LOG_DEBUG(Service_NFC, "called"); + } +}; + +class ISystem final : public ServiceFramework<ISystem> { +public: + explicit ISystem() : ServiceFramework{"ISystem"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {1, nullptr, "Finalize"}, + {2, nullptr, "GetState"}, + {3, nullptr, "IsNfcEnabled"}, + {100, nullptr, "SetNfcEnabled"}, + {400, nullptr, "InitializeSystem"}, + {401, nullptr, "FinalizeSystem"}, + {402, nullptr, "GetState"}, + {403, nullptr, "IsNfcEnabled"}, + {404, nullptr, "ListDevices"}, + {405, nullptr, "GetDeviceState"}, + {406, nullptr, "GetNpadId"}, + {407, nullptr, "AttachAvailabilityChangeEvent"}, + {408, nullptr, "StartDetection"}, + {409, nullptr, "StopDetection"}, + {410, nullptr, "GetTagInfo"}, + {411, nullptr, "AttachActivateEvent"}, + {412, nullptr, "AttachDeactivateEvent"}, + {500, nullptr, "SetNfcEnabled"}, + {1000, nullptr, "ReadMifare"}, + {1001, nullptr, "WriteMifare"}, + {1300, nullptr, "SendCommandByPassThrough"}, + {1301, nullptr, "KeepPassThroughSession"}, + {1302, nullptr, "ReleasePassThroughSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class NFC_SYS final : public ServiceFramework<NFC_SYS> { +public: + explicit NFC_SYS() : ServiceFramework{"nfc:sys"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &NFC_SYS::CreateSystemInterface, "CreateSystemInterface"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void CreateSystemInterface(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<ISystem>(); + + LOG_DEBUG(Service_NFC, "called"); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<NFC_AM>()->InstallAsService(sm); + std::make_shared<NFC_MF_U>()->InstallAsService(sm); + std::make_shared<NFC_U>()->InstallAsService(sm); + std::make_shared<NFC_SYS>()->InstallAsService(sm); +} + +} // namespace Service::NFC diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h new file mode 100644 index 000000000..4d2d815f9 --- /dev/null +++ b/src/core/hle/service/nfc/nfc.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::NFC { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::NFC diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 89c703310..98017267c 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp @@ -2,12 +2,459 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" #include "core/hle/service/ns/ns.h" #include "core/hle/service/ns/pl_u.h" namespace Service::NS { +class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> { +public: + explicit IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "CreateUserAccount"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> { +public: + explicit IApplicationManagerInterface() : ServiceFramework{"IApplicationManagerInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "ListApplicationRecord"}, + {1, nullptr, "GenerateApplicationRecordCount"}, + {2, nullptr, "GetApplicationRecordUpdateSystemEvent"}, + {3, nullptr, "GetApplicationViewDeprecated"}, + {4, nullptr, "DeleteApplicationEntity"}, + {5, nullptr, "DeleteApplicationCompletely"}, + {6, nullptr, "IsAnyApplicationEntityRedundant"}, + {7, nullptr, "DeleteRedundantApplicationEntity"}, + {8, nullptr, "IsApplicationEntityMovable"}, + {9, nullptr, "MoveApplicationEntity"}, + {11, nullptr, "CalculateApplicationOccupiedSize"}, + {16, nullptr, "PushApplicationRecord"}, + {17, nullptr, "ListApplicationRecordContentMeta"}, + {19, nullptr, "LaunchApplication"}, + {21, nullptr, "GetApplicationContentPath"}, + {22, nullptr, "TerminateApplication"}, + {23, nullptr, "ResolveApplicationContentPath"}, + {26, nullptr, "BeginInstallApplication"}, + {27, nullptr, "DeleteApplicationRecord"}, + {30, nullptr, "RequestApplicationUpdateInfo"}, + {32, nullptr, "CancelApplicationDownload"}, + {33, nullptr, "ResumeApplicationDownload"}, + {35, nullptr, "UpdateVersionList"}, + {36, nullptr, "PushLaunchVersion"}, + {37, nullptr, "ListRequiredVersion"}, + {38, nullptr, "CheckApplicationLaunchVersion"}, + {39, nullptr, "CheckApplicationLaunchRights"}, + {40, nullptr, "GetApplicationLogoData"}, + {41, nullptr, "CalculateApplicationDownloadRequiredSize"}, + {42, nullptr, "CleanupSdCard"}, + {43, nullptr, "CheckSdCardMountStatus"}, + {44, nullptr, "GetSdCardMountStatusChangedEvent"}, + {45, nullptr, "GetGameCardAttachmentEvent"}, + {46, nullptr, "GetGameCardAttachmentInfo"}, + {47, nullptr, "GetTotalSpaceSize"}, + {48, nullptr, "GetFreeSpaceSize"}, + {49, nullptr, "GetSdCardRemovedEvent"}, + {52, nullptr, "GetGameCardUpdateDetectionEvent"}, + {53, nullptr, "DisableApplicationAutoDelete"}, + {54, nullptr, "EnableApplicationAutoDelete"}, + {55, nullptr, "GetApplicationDesiredLanguage"}, + {56, nullptr, "SetApplicationTerminateResult"}, + {57, nullptr, "ClearApplicationTerminateResult"}, + {58, nullptr, "GetLastSdCardMountUnexpectedResult"}, + {59, nullptr, "ConvertApplicationLanguageToLanguageCode"}, + {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, + {61, nullptr, "GetBackgroundDownloadStressTaskInfo"}, + {62, nullptr, "GetGameCardStopper"}, + {63, nullptr, "IsSystemProgramInstalled"}, + {64, nullptr, "StartApplyDeltaTask"}, + {65, nullptr, "GetRequestServerStopper"}, + {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"}, + {67, nullptr, "CancelApplicationApplyDelta"}, + {68, nullptr, "ResumeApplicationApplyDelta"}, + {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"}, + {70, nullptr, "ResumeAll"}, + {71, nullptr, "GetStorageSize"}, + {80, nullptr, "RequestDownloadApplication"}, + {81, nullptr, "RequestDownloadAddOnContent"}, + {82, nullptr, "DownloadApplication"}, + {83, nullptr, "CheckApplicationResumeRights"}, + {84, nullptr, "GetDynamicCommitEvent"}, + {85, nullptr, "RequestUpdateApplication2"}, + {86, nullptr, "EnableApplicationCrashReport"}, + {87, nullptr, "IsApplicationCrashReportEnabled"}, + {90, nullptr, "BoostSystemMemoryResourceLimit"}, + {100, nullptr, "ResetToFactorySettings"}, + {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, + {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, + {200, nullptr, "CalculateUserSaveDataStatistics"}, + {201, nullptr, "DeleteUserSaveDataAll"}, + {210, nullptr, "DeleteUserSystemSaveData"}, + {220, nullptr, "UnregisterNetworkServiceAccount"}, + {300, nullptr, "GetApplicationShellEvent"}, + {301, nullptr, "PopApplicationShellEventInfo"}, + {302, nullptr, "LaunchLibraryApplet"}, + {303, nullptr, "TerminateLibraryApplet"}, + {304, nullptr, "LaunchSystemApplet"}, + {305, nullptr, "TerminateSystemApplet"}, + {306, nullptr, "LaunchOverlayApplet"}, + {307, nullptr, "TerminateOverlayApplet"}, + {400, nullptr, "GetApplicationControlData"}, + {401, nullptr, "InvalidateAllApplicationControlCache"}, + {402, nullptr, "RequestDownloadApplicationControlData"}, + {403, nullptr, "GetMaxApplicationControlCacheCount"}, + {404, nullptr, "InvalidateApplicationControlCache"}, + {405, nullptr, "ListApplicationControlCacheEntryInfo"}, + {502, nullptr, "RequestCheckGameCardRegistration"}, + {503, nullptr, "RequestGameCardRegistrationGoldPoint"}, + {504, nullptr, "RequestRegisterGameCard"}, + {505, nullptr, "GetGameCardMountFailureEvent"}, + {506, nullptr, "IsGameCardInserted"}, + {507, nullptr, "EnsureGameCardAccess"}, + {508, nullptr, "GetLastGameCardMountFailureResult"}, + {509, nullptr, "ListApplicationIdOnGameCard"}, + {600, nullptr, "CountApplicationContentMeta"}, + {601, nullptr, "ListApplicationContentMetaStatus"}, + {602, nullptr, "ListAvailableAddOnContent"}, + {603, nullptr, "GetOwnedApplicationContentMetaStatus"}, + {604, nullptr, "RegisterContentsExternalKey"}, + {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, + {606, nullptr, "GetContentMetaStorage"}, + {700, nullptr, "PushDownloadTaskList"}, + {701, nullptr, "ClearTaskStatusList"}, + {702, nullptr, "RequestDownloadTaskList"}, + {703, nullptr, "RequestEnsureDownloadTask"}, + {704, nullptr, "ListDownloadTaskStatus"}, + {705, nullptr, "RequestDownloadTaskListData"}, + {800, nullptr, "RequestVersionList"}, + {801, nullptr, "ListVersionList"}, + {802, nullptr, "RequestVersionListData"}, + {900, nullptr, "GetApplicationRecord"}, + {901, nullptr, "GetApplicationRecordProperty"}, + {902, nullptr, "EnableApplicationAutoUpdate"}, + {903, nullptr, "DisableApplicationAutoUpdate"}, + {904, nullptr, "TouchApplication"}, + {905, nullptr, "RequestApplicationUpdate"}, + {906, nullptr, "IsApplicationUpdateRequested"}, + {907, nullptr, "WithdrawApplicationUpdateRequest"}, + {908, nullptr, "ListApplicationRecordInstalledContentMeta"}, + {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"}, + {1000, nullptr, "RequestVerifyApplicationDeprecated"}, + {1001, nullptr, "CorruptApplicationForDebug"}, + {1002, nullptr, "RequestVerifyAddOnContentsRights"}, + {1003, nullptr, "RequestVerifyApplication"}, + {1004, nullptr, "CorruptContentForDebug"}, + {1200, nullptr, "NeedsUpdateVulnerability"}, + {1300, nullptr, "IsAnyApplicationEntityInstalled"}, + {1301, nullptr, "DeleteApplicationContentEntities"}, + {1302, nullptr, "CleanupUnrecordedApplicationEntity"}, + {1303, nullptr, "CleanupAddOnContentsWithNoRights"}, + {1304, nullptr, "DeleteApplicationContentEntity"}, + {1305, nullptr, "TryDeleteRunningApplicationEntity"}, + {1306, nullptr, "TryDeleteRunningApplicationCompletely"}, + {1307, nullptr, "TryDeleteRunningApplicationContentEntities"}, + {1400, nullptr, "PrepareShutdown"}, + {1500, nullptr, "FormatSdCard"}, + {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, + {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"}, + {1504, nullptr, "InsertSdCard"}, + {1505, nullptr, "RemoveSdCard"}, + {1600, nullptr, "GetSystemSeedForPseudoDeviceId"}, + {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"}, + {1700, nullptr, "ListApplicationDownloadingContentMeta"}, + {1701, nullptr, "GetApplicationView"}, + {1702, nullptr, "GetApplicationDownloadTaskStatus"}, + {1703, nullptr, "GetApplicationViewDownloadErrorContext"}, + {1800, nullptr, "IsNotificationSetupCompleted"}, + {1801, nullptr, "GetLastNotificationInfoCount"}, + {1802, nullptr, "ListLastNotificationInfo"}, + {1803, nullptr, "ListNotificationTask"}, + {1900, nullptr, "IsActiveAccount"}, + {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"}, + {1902, nullptr, "GetApplicationTicketInfo"}, + {2000, nullptr, "GetSystemDeliveryInfo"}, + {2001, nullptr, "SelectLatestSystemDeliveryInfo"}, + {2002, nullptr, "VerifyDeliveryProtocolVersion"}, + {2003, nullptr, "GetApplicationDeliveryInfo"}, + {2004, nullptr, "HasAllContentsToDeliver"}, + {2005, nullptr, "CompareApplicationDeliveryInfo"}, + {2006, nullptr, "CanDeliverApplication"}, + {2007, nullptr, "ListContentMetaKeyToDeliverApplication"}, + {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"}, + {2009, nullptr, "EstimateRequiredSize"}, + {2010, nullptr, "RequestReceiveApplication"}, + {2011, nullptr, "CommitReceiveApplication"}, + {2012, nullptr, "GetReceiveApplicationProgress"}, + {2013, nullptr, "RequestSendApplication"}, + {2014, nullptr, "GetSendApplicationProgress"}, + {2015, nullptr, "CompareSystemDeliveryInfo"}, + {2016, nullptr, "ListNotCommittedContentMeta"}, + {2017, nullptr, "CreateDownloadTask"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { +public: + explicit IApplicationVersionInterface() : ServiceFramework{"IApplicationVersionInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetLaunchRequiredVersion"}, + {1, nullptr, "UpgradeLaunchRequiredVersion"}, + {35, nullptr, "UpdateVersionList"}, + {36, nullptr, "PushLaunchVersion"}, + {37, nullptr, "ListRequiredVersion"}, + {800, nullptr, "RequestVersionList"}, + {801, nullptr, "ListVersionList"}, + {802, nullptr, "RequestVersionListData"}, + {1000, nullptr, "PerformAutoUpdate"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> { +public: + explicit IContentManagerInterface() : ServiceFramework{"IContentManagerInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {11, nullptr, "CalculateApplicationOccupiedSize"}, + {43, nullptr, "CheckSdCardMountStatus"}, + {47, nullptr, "GetTotalSpaceSize"}, + {48, nullptr, "GetFreeSpaceSize"}, + {600, nullptr, "CountApplicationContentMeta"}, + {601, nullptr, "ListApplicationContentMetaStatus"}, + {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, + {607, nullptr, "IsAnyApplicationRunning"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IDocumentInterface final : public ServiceFramework<IDocumentInterface> { +public: + explicit IDocumentInterface() : ServiceFramework{"IDocumentInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {21, nullptr, "GetApplicationContentPath"}, + {23, nullptr, "ResolveApplicationContentPath"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> { +public: + explicit IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {701, nullptr, "ClearTaskStatusList"}, + {702, nullptr, "RequestDownloadTaskList"}, + {703, nullptr, "RequestEnsureDownloadTask"}, + {704, nullptr, "ListDownloadTaskStatus"}, + {705, nullptr, "RequestDownloadTaskListData"}, + {706, nullptr, "TryCommitCurrentApplicationDownloadTask"}, + {707, nullptr, "EnableAutoCommit"}, + {708, nullptr, "DisableAutoCommit"}, + {709, nullptr, "TriggerDynamicCommitEvent"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IECommerceInterface final : public ServiceFramework<IECommerceInterface> { +public: + explicit IECommerceInterface() : ServiceFramework{"IECommerceInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RequestLinkDevice"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> { +public: + explicit IFactoryResetInterface() : ServiceFramework{"IFactoryResetInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {100, nullptr, "ResetToFactorySettings"}, + {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, + {102, nullptr, "ResetToFactorySettingsForRefurbishment "}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class NS final : public ServiceFramework<NS> { +public: + explicit NS(const char* name) : ServiceFramework{name} { + // clang-format off + static const FunctionInfo functions[] = { + {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, + {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"}, + {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"}, + {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"}, + {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"}, + {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"}, + {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"}, + {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + template <typename T> + void PushInterface(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<T>(); + + LOG_DEBUG(Service_NS, "called"); + } +}; + +class NS_DEV final : public ServiceFramework<NS_DEV> { +public: + explicit NS_DEV() : ServiceFramework{"ns:dev"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "LaunchProgram"}, + {1, nullptr, "TerminateProcess"}, + {2, nullptr, "TerminateProgram"}, + {3, nullptr, "GetShellEventHandle"}, + {4, nullptr, "GetShellEventInfo"}, + {5, nullptr, "TerminateApplication"}, + {6, nullptr, "PrepareLaunchProgramFromHost"}, + {7, nullptr, "LaunchApplication"}, + {8, nullptr, "LaunchApplicationWithStorageId"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> { +public: + explicit ISystemUpdateControl() : ServiceFramework{"ISystemUpdateControl"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "HasDownloaded"}, + {1, nullptr, "RequestCheckLatestUpdate"}, + {2, nullptr, "RequestDownloadLatestUpdate"}, + {3, nullptr, "GetDownloadProgress"}, + {4, nullptr, "ApplyDownloadedUpdate"}, + {5, nullptr, "RequestPrepareCardUpdate"}, + {6, nullptr, "GetPrepareCardUpdateProgress"}, + {7, nullptr, "HasPreparedCardUpdate"}, + {8, nullptr, "ApplyCardUpdate"}, + {9, nullptr, "GetDownloadedEulaDataSize"}, + {10, nullptr, "GetDownloadedEulaData"}, + {11, nullptr, "SetupCardUpdate"}, + {12, nullptr, "GetPreparedCardUpdateEulaDataSize"}, + {13, nullptr, "GetPreparedCardUpdateEulaData"}, + {14, nullptr, "SetupCardUpdateViaSystemUpdater"}, + {15, nullptr, "HasReceived"}, + {16, nullptr, "RequestReceiveSystemUpdate"}, + {17, nullptr, "GetReceiveProgress"}, + {18, nullptr, "ApplyReceivedUpdate"}, + {19, nullptr, "GetReceivedEulaDataSize"}, + {20, nullptr, "GetReceivedEulaData"}, + {21, nullptr, "SetupToReceiveSystemUpdate"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class NS_SU final : public ServiceFramework<NS_SU> { +public: + explicit NS_SU() : ServiceFramework{"ns:su"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetBackgroundNetworkUpdateState"}, + {1, &NS_SU::OpenSystemUpdateControl, "OpenSystemUpdateControl"}, + {2, nullptr, "NotifyExFatDriverRequired"}, + {3, nullptr, "ClearExFatDriverStatusForDebug"}, + {4, nullptr, "RequestBackgroundNetworkUpdate"}, + {5, nullptr, "NotifyBackgroundNetworkUpdate"}, + {6, nullptr, "NotifyExFatDriverDownloadedForDebug"}, + {9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"}, + {10, nullptr, "NotifySystemUpdateForContentDelivery"}, + {11, nullptr, "PrepareShutdown"}, + {16, nullptr, "DestroySystemUpdateTask"}, + {17, nullptr, "RequestSendSystemUpdate"}, + {18, nullptr, "GetSendSystemUpdateProgress"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void OpenSystemUpdateControl(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<ISystemUpdateControl>(); + + LOG_DEBUG(Service_NS, "called"); + } +}; + +class NS_VM final : public ServiceFramework<NS_VM> { +public: + explicit NS_VM() : ServiceFramework{"ns:vm"} { + // clang-format off + static const FunctionInfo functions[] = { + {1200, nullptr, "NeedsUpdateVulnerability"}, + {1201, nullptr, "UpdateSafeSystemVersionForDebug"}, + {1202, nullptr, "GetSafeSystemVersion"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + void InstallInterfaces(SM::ServiceManager& service_manager) { + std::make_shared<NS>("ns:am2")->InstallAsService(service_manager); + std::make_shared<NS>("ns:ec")->InstallAsService(service_manager); + std::make_shared<NS>("ns:rid")->InstallAsService(service_manager); + std::make_shared<NS>("ns:rt")->InstallAsService(service_manager); + std::make_shared<NS>("ns:web")->InstallAsService(service_manager); + + std::make_shared<NS_DEV>()->InstallAsService(service_manager); + std::make_shared<NS_SU>()->InstallAsService(service_manager); + std::make_shared<NS_VM>()->InstallAsService(service_manager); + std::make_shared<PL_U>()->InstallAsService(service_manager); } diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index ed69a4325..8bc49935a 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -7,8 +7,8 @@ #include "core/core.h" #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" #include "core/hle/service/nvdrv/devices/nvmap.h" +#include "video_core/gpu.h" #include "video_core/renderer_base.h" -#include "video_core/video_core.h" namespace Service::Nvidia::Devices { @@ -30,9 +30,9 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 addr, offset, width, height, stride, static_cast<PixelFormat>(format), transform, crop_rect}; - Core::System::GetInstance().perf_stats.EndGameFrame(); - - VideoCore::g_renderer->SwapBuffers(framebuffer); + auto& instance = Core::System::GetInstance(); + instance.perf_stats.EndGameFrame(); + instance.Renderer().SwapBuffers(framebuffer); } } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 57b128b40..be2b79256 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -2,14 +2,15 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <cinttypes> +#include <cstring> #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" #include "core/hle/service/nvdrv/devices/nvmap.h" +#include "video_core/memory_manager.h" +#include "video_core/rasterizer_interface.h" #include "video_core/renderer_base.h" -#include "video_core/video_core.h" namespace Service::Nvidia::Devices { @@ -150,15 +151,16 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); - auto& gpu = Core::System::GetInstance().GPU(); - - auto itr = buffer_mappings.find(params.offset); - + const auto itr = buffer_mappings.find(params.offset); ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); + auto& system_instance = Core::System::GetInstance(); + // Remove this memory region from the rasterizer cache. - VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(params.offset, itr->second.size); + system_instance.Renderer().Rasterizer().FlushAndInvalidateRegion(params.offset, + itr->second.size); + auto& gpu = system_instance.GPU(); params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); buffer_mappings.erase(itr->second.offset); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 671b092e1..5685eb2be 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -2,6 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cstdlib> +#include <cstring> + #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 090261a60..6b496e9fe 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h @@ -5,8 +5,6 @@ #pragma once #include <array> -#include <cstdlib> -#include <cstring> #include <vector> #include "common/common_types.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 44e062f50..ae421247d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -2,7 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <cinttypes> +#include <cstring> #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" @@ -97,7 +97,9 @@ u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { LOG_DEBUG(Service_NVDRV, "called"); IoctlActiveSlotMask params{}; - std::memcpy(¶ms, input.data(), input.size()); + if (input.size() > 0) { + std::memcpy(¶ms, input.data(), input.size()); + } params.slot = 0x07; params.mask = 0x01; std::memcpy(output.data(), ¶ms, output.size()); @@ -107,7 +109,9 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { LOG_DEBUG(Service_NVDRV, "called"); IoctlZcullGetCtxSize params{}; - std::memcpy(¶ms, input.data(), input.size()); + if (input.size() > 0) { + std::memcpy(¶ms, input.data(), input.size()); + } params.size = 0x1; std::memcpy(output.data(), ¶ms, output.size()); return 0; @@ -116,7 +120,11 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { LOG_DEBUG(Service_NVDRV, "called"); IoctlNvgpuGpuZcullGetInfoArgs params{}; - std::memcpy(¶ms, input.data(), input.size()); + + if (input.size() > 0) { + std::memcpy(¶ms, input.data(), input.size()); + } + params.width_align_pixels = 0x20; params.height_align_pixels = 0x20; params.pixel_squares_by_aliquots = 0x400; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 126782573..116dabedb 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -2,12 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <cinttypes> -#include <map> +#include <cstring> #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" +#include "core/memory.h" +#include "video_core/gpu.h" +#include "video_core/memory_manager.h" namespace Service::Nvidia::Devices { @@ -132,9 +134,12 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", params.address, params.num_entries, params.flags); - auto entries = std::vector<IoctlGpfifoEntry>(); - entries.resize(params.num_entries); - std::memcpy(&entries[0], &input.data()[sizeof(IoctlSubmitGpfifo)], + ASSERT_MSG(input.size() == + sizeof(IoctlSubmitGpfifo) + params.num_entries * sizeof(IoctlGpfifoEntry), + "Incorrect input size"); + + std::vector<IoctlGpfifoEntry> entries(params.num_entries); + std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)], params.num_entries * sizeof(IoctlGpfifoEntry)); for (auto entry : entries) { Tegra::GPUVAddr va_addr = entry.Address(); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index aa8df2e6e..650ed8fbc 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -6,6 +6,7 @@ #include <memory> #include <vector> +#include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index b51c73ee8..364619e67 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cstring> + #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index 0192aecdd..6ad74421b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h @@ -4,11 +4,9 @@ #pragma once -#include <array> -#include <cstdlib> -#include <cstring> #include <vector> #include "common/common_types.h" +#include "common/swap.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" namespace Service::Nvidia::Devices { diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 724eeb139..e9305bfb3 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -3,7 +3,7 @@ // Refer to the license.txt file included. #include <algorithm> -#include <cinttypes> +#include <cstring> #include "common/assert.h" #include "common/logging/log.h" diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 959b5ba29..1c3529bb6 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h @@ -5,7 +5,6 @@ #pragma once #include <memory> -#include <string> #include "core/hle/kernel/event.h" #include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 1555ea806..e8b30921a 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -54,7 +54,7 @@ u32 Module::Open(const std::string& device_name) { return fd; } -u32 Module::Ioctl(u32 fd, u32_le command, const std::vector<u8>& input, std::vector<u8>& output) { +u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output) { auto itr = open_files.find(fd); ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); diff --git a/src/core/hle/service/nvdrv/nvmemp.cpp b/src/core/hle/service/nvdrv/nvmemp.cpp index 9ca6e5512..0e8e21bad 100644 --- a/src/core/hle/service/nvdrv/nvmemp.cpp +++ b/src/core/hle/service/nvdrv/nvmemp.cpp @@ -4,8 +4,6 @@ #include "common/assert.h" #include "common/logging/log.h" -#include "core/hle/ipc_helpers.h" -#include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/nvdrv/nvmemp.h" namespace Service::Nvidia { diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 7132b18ad..adf180509 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -4,9 +4,8 @@ #include <algorithm> -#include "common/alignment.h" -#include "common/scope_exit.h" -#include "core/core_timing.h" +#include "common/assert.h" +#include "common/logging/log.h" #include "core/hle/service/nvflinger/buffer_queue.h" namespace Service { diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 5344441e1..570aa8493 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -3,8 +3,11 @@ // Refer to the license.txt file included. #include <algorithm> +#include <boost/optional.hpp> #include "common/alignment.h" +#include "common/assert.h" +#include "common/logging/log.h" #include "common/microprofile.h" #include "common/scope_exit.h" #include "core/core.h" @@ -31,7 +34,7 @@ NVFlinger::NVFlinger() { // Schedule the screen composition events composition_event = - CoreTiming::RegisterEvent("ScreenCompositioin", [this](u64 userdata, int cycles_late) { + CoreTiming::RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) { Compose(); CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event); }); @@ -43,7 +46,7 @@ NVFlinger::~NVFlinger() { CoreTiming::UnscheduleEvent(composition_event, 0); } -u64 NVFlinger::OpenDisplay(const std::string& name) { +u64 NVFlinger::OpenDisplay(std::string_view name) { LOG_WARNING(Service, "Opening display {}", name); // TODO(Subv): Currently we only support the Default display. @@ -127,9 +130,11 @@ void NVFlinger::Compose() { MicroProfileFlip(); if (buffer == boost::none) { + auto& system_instance = Core::System::GetInstance(); + // There was no queued buffer to draw, render previous frame - Core::System::GetInstance().perf_stats.EndGameFrame(); - VideoCore::g_renderer->SwapBuffers({}); + system_instance.perf_stats.EndGameFrame(); + system_instance.Renderer().SwapBuffers({}); continue; } diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 2c908297b..5374df175 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h @@ -5,7 +5,11 @@ #pragma once #include <memory> -#include <boost/optional.hpp> +#include <string> +#include <string_view> +#include <vector> + +#include "common/common_types.h" #include "core/hle/kernel/event.h" namespace CoreTiming { @@ -41,7 +45,7 @@ public: ~NVFlinger(); /// Opens the specified display and returns the id. - u64 OpenDisplay(const std::string& name); + u64 OpenDisplay(std::string_view name); /// Creates a layer on the specified display and returns the layer id. u64 CreateLayer(u64 display_id); diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp new file mode 100644 index 000000000..39cf05eba --- /dev/null +++ b/src/core/hle/service/pcie/pcie.cpp @@ -0,0 +1,64 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "core/hle/service/pcie/pcie.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::PCIe { + +class ISession final : public ServiceFramework<ISession> { +public: + explicit ISession() : ServiceFramework{"ISession"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "QueryFunctions"}, + {1, nullptr, "AcquireFunction"}, + {2, nullptr, "ReleaseFunction"}, + {3, nullptr, "GetFunctionState"}, + {4, nullptr, "GetBarProfile"}, + {5, nullptr, "ReadConfig"}, + {6, nullptr, "WriteConfig"}, + {7, nullptr, "ReadBarRegion"}, + {8, nullptr, "WriteBarRegion"}, + {9, nullptr, "FindCapability"}, + {10, nullptr, "FindExtendedCapability"}, + {11, nullptr, "MapDma"}, + {12, nullptr, "UnmapDma"}, + {13, nullptr, "UnmapDmaBusAddress"}, + {14, nullptr, "GetDmaBusAddress"}, + {15, nullptr, "GetDmaBusAddressRange"}, + {16, nullptr, "SetDmaEnable"}, + {17, nullptr, "AcquireIrq"}, + {18, nullptr, "ReleaseIrq"}, + {19, nullptr, "SetIrqEnable"}, + {20, nullptr, "SetAspmEnable"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class PCIe final : public ServiceFramework<PCIe> { +public: + explicit PCIe() : ServiceFramework{"pcie"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RegisterClassDriver"}, + {1, nullptr, "QueryFunctionsUnregistered"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<PCIe>()->InstallAsService(sm); +} + +} // namespace Service::PCIe diff --git a/src/core/hle/service/pcie/pcie.h b/src/core/hle/service/pcie/pcie.h new file mode 100644 index 000000000..59c22ca45 --- /dev/null +++ b/src/core/hle/service/pcie/pcie.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::PCIe { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::PCIe diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp new file mode 100644 index 000000000..d6891a659 --- /dev/null +++ b/src/core/hle/service/pcv/pcv.cpp @@ -0,0 +1,84 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "core/hle/service/pcv/pcv.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::PCV { + +class PCV final : public ServiceFramework<PCV> { +public: + explicit PCV() : ServiceFramework{"pcv"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "SetPowerEnabled"}, + {1, nullptr, "SetClockEnabled"}, + {2, nullptr, "SetClockRate"}, + {3, nullptr, "GetClockRate"}, + {4, nullptr, "GetState"}, + {5, nullptr, "GetPossibleClockRates"}, + {6, nullptr, "SetMinVClockRate"}, + {7, nullptr, "SetReset"}, + {8, nullptr, "SetVoltageEnabled"}, + {9, nullptr, "GetVoltageEnabled"}, + {10, nullptr, "GetVoltageRange"}, + {11, nullptr, "SetVoltageValue"}, + {12, nullptr, "GetVoltageValue"}, + {13, nullptr, "GetTemperatureThresholds"}, + {14, nullptr, "SetTemperature"}, + {15, nullptr, "Initialize"}, + {16, nullptr, "IsInitialized"}, + {17, nullptr, "Finalize"}, + {18, nullptr, "PowerOn"}, + {19, nullptr, "PowerOff"}, + {20, nullptr, "ChangeVoltage"}, + {21, nullptr, "GetPowerClockInfoEvent"}, + {22, nullptr, "GetOscillatorClock"}, + {23, nullptr, "GetDvfsTable"}, + {24, nullptr, "GetModuleStateTable"}, + {25, nullptr, "GetPowerDomainStateTable"}, + {26, nullptr, "GetFuseInfo"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class PCV_ARB final : public ServiceFramework<PCV_ARB> { +public: + explicit PCV_ARB() : ServiceFramework{"pcv:arb"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "ReleaseControl"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class PCV_IMM final : public ServiceFramework<PCV_IMM> { +public: + explicit PCV_IMM() : ServiceFramework{"pcv:imm"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "SetClockRate"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<PCV>()->InstallAsService(sm); + std::make_shared<PCV_ARB>()->InstallAsService(sm); + std::make_shared<PCV_IMM>()->InstallAsService(sm); +} + +} // namespace Service::PCV diff --git a/src/core/hle/service/pcv/pcv.h b/src/core/hle/service/pcv/pcv.h new file mode 100644 index 000000000..219a893c3 --- /dev/null +++ b/src/core/hle/service/pcv/pcv.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::PCV { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::PCV diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp new file mode 100644 index 000000000..bbad870a2 --- /dev/null +++ b/src/core/hle/service/psc/psc.cpp @@ -0,0 +1,77 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/service/psc/psc.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" + +namespace Service::PSC { + +class PSC_C final : public ServiceFramework<PSC_C> { +public: + explicit PSC_C() : ServiceFramework{"psc:c"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "Unknown5"}, + {5, nullptr, "Unknown6"}, + {6, nullptr, "Unknown7"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IPmModule final : public ServiceFramework<IPmModule> { +public: + explicit IPmModule() : ServiceFramework{"IPmModule"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {1, nullptr, "GetRequest"}, + {2, nullptr, "Acknowledge"}, + {3, nullptr, "Unknown1"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class PSC_M final : public ServiceFramework<PSC_M> { +public: + explicit PSC_M() : ServiceFramework{"psc:m"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &PSC_M::GetPmModule, "GetPmModule"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void GetPmModule(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IPmModule>(); + + LOG_DEBUG(Service_PSC, "called"); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<PSC_C>()->InstallAsService(sm); + std::make_shared<PSC_M>()->InstallAsService(sm); +} + +} // namespace Service::PSC diff --git a/src/core/hle/service/psc/psc.h b/src/core/hle/service/psc/psc.h new file mode 100644 index 000000000..5052eb02c --- /dev/null +++ b/src/core/hle/service/psc/psc.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::PSC { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::PSC diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 8b84fd349..889cdd41a 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -19,28 +19,42 @@ #include "core/hle/service/am/am.h" #include "core/hle/service/aoc/aoc_u.h" #include "core/hle/service/apm/apm.h" +#include "core/hle/service/arp/arp.h" #include "core/hle/service/audio/audio.h" #include "core/hle/service/bcat/bcat.h" +#include "core/hle/service/bpc/bpc.h" +#include "core/hle/service/btdrv/btdrv.h" +#include "core/hle/service/btm/btm.h" +#include "core/hle/service/caps/caps.h" #include "core/hle/service/erpt/erpt.h" #include "core/hle/service/es/es.h" #include "core/hle/service/eupld/eupld.h" #include "core/hle/service/fatal/fatal.h" +#include "core/hle/service/fgm/fgm.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/friend/friend.h" #include "core/hle/service/grc/grc.h" #include "core/hle/service/hid/hid.h" +#include "core/hle/service/lbl/lbl.h" #include "core/hle/service/ldn/ldn.h" #include "core/hle/service/ldr/ldr.h" #include "core/hle/service/lm/lm.h" +#include "core/hle/service/mig/mig.h" +#include "core/hle/service/mii/mii.h" #include "core/hle/service/mm/mm_u.h" +#include "core/hle/service/ncm/ncm.h" +#include "core/hle/service/nfc/nfc.h" #include "core/hle/service/nfp/nfp.h" #include "core/hle/service/nifm/nifm.h" #include "core/hle/service/nim/nim.h" #include "core/hle/service/ns/ns.h" #include "core/hle/service/nvdrv/nvdrv.h" +#include "core/hle/service/pcie/pcie.h" #include "core/hle/service/pctl/pctl.h" +#include "core/hle/service/pcv/pcv.h" #include "core/hle/service/pm/pm.h" #include "core/hle/service/prepo/prepo.h" +#include "core/hle/service/psc/psc.h" #include "core/hle/service/service.h" #include "core/hle/service/set/settings.h" #include "core/hle/service/sm/controller.h" @@ -49,7 +63,9 @@ #include "core/hle/service/spl/module.h" #include "core/hle/service/ssl/ssl.h" #include "core/hle/service/time/time.h" +#include "core/hle/service/usb/usb.h" #include "core/hle/service/vi/vi.h" +#include "core/hle/service/wlan/wlan.h" using Kernel::ClientPort; using Kernel::ServerPort; @@ -193,34 +209,50 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) { AM::InstallInterfaces(*sm, nv_flinger); AOC::InstallInterfaces(*sm); APM::InstallInterfaces(*sm); - BCAT::InstallInterfaces(*sm); + ARP::InstallInterfaces(*sm); Audio::InstallInterfaces(*sm); + BCAT::InstallInterfaces(*sm); + BPC::InstallInterfaces(*sm); + BtDrv::InstallInterfaces(*sm); + BTM::InstallInterfaces(*sm); + Capture::InstallInterfaces(*sm); ERPT::InstallInterfaces(*sm); ES::InstallInterfaces(*sm); EUPLD::InstallInterfaces(*sm); Fatal::InstallInterfaces(*sm); + FGM::InstallInterfaces(*sm); FileSystem::InstallInterfaces(*sm); Friend::InstallInterfaces(*sm); GRC::InstallInterfaces(*sm); HID::InstallInterfaces(*sm); + LBL::InstallInterfaces(*sm); LDN::InstallInterfaces(*sm); LDR::InstallInterfaces(*sm); LM::InstallInterfaces(*sm); + Migration::InstallInterfaces(*sm); + Mii::InstallInterfaces(*sm); MM::InstallInterfaces(*sm); + NCM::InstallInterfaces(*sm); + NFC::InstallInterfaces(*sm); NFP::InstallInterfaces(*sm); NIFM::InstallInterfaces(*sm); NIM::InstallInterfaces(*sm); NS::InstallInterfaces(*sm); Nvidia::InstallInterfaces(*sm); + PCIe::InstallInterfaces(*sm); PCTL::InstallInterfaces(*sm); + PCV::InstallInterfaces(*sm); PlayReport::InstallInterfaces(*sm); PM::InstallInterfaces(*sm); + PSC::InstallInterfaces(*sm); + Set::InstallInterfaces(*sm); Sockets::InstallInterfaces(*sm); SPL::InstallInterfaces(*sm); SSL::InstallInterfaces(*sm); Time::InstallInterfaces(*sm); + USB::InstallInterfaces(*sm); VI::InstallInterfaces(*sm, nv_flinger); - Set::InstallInterfaces(*sm); + WLAN::InstallInterfaces(*sm); LOG_DEBUG(Service, "initialized OK"); } diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 180f22703..046c5e18d 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -8,10 +8,9 @@ #include <string> #include <unordered_map> #include <boost/container/flat_map.hpp> -#include "common/bit_field.h" #include "common/common_types.h" #include "core/hle/kernel/hle_ipc.h" -#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/object.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace Service diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 1651f6122..a461e72ec 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -8,6 +8,7 @@ #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/service/set/set.h" +#include "core/settings.h" namespace Service::Set { @@ -31,6 +32,10 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{ LanguageCode::ZH_HANT, }}; +LanguageCode GetLanguageCodeFromIndex(size_t index) { + return available_language_codes.at(index); +} + void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { ctx.WriteBuffer(available_language_codes); @@ -49,9 +54,17 @@ void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_SET, "called"); } +void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.Push(static_cast<u64>(available_language_codes[Settings::values.language_index])); + + LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index); +} + SET::SET() : ServiceFramework("set") { static const FunctionInfo functions[] = { - {0, nullptr, "GetLanguageCode"}, + {0, &SET::GetLanguageCode, "GetLanguageCode"}, {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, {2, nullptr, "MakeLanguageCode"}, {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h index a2472ec4c..4232b6162 100644 --- a/src/core/hle/service/set/set.h +++ b/src/core/hle/service/set/set.h @@ -28,6 +28,7 @@ enum class LanguageCode : u64 { ZH_HANS = 0x00736E61482D687A, ZH_HANT = 0x00746E61482D687A, }; +LanguageCode GetLanguageCodeFromIndex(size_t idx); class SET final : public ServiceFramework<SET> { public: @@ -35,6 +36,7 @@ public: ~SET() = default; private: + void GetLanguageCode(Kernel::HLERequestContext& ctx); void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx); void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx); }; diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index e2a00e4f6..e8ea62f08 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -4,9 +4,11 @@ #pragma once +#include <memory> #include <string> #include <unordered_map> -#include "core/hle/kernel/kernel.h" + +#include "core/hle/kernel/object.h" #include "core/hle/result.h" #include "core/hle/service/service.h" @@ -19,6 +21,8 @@ class SessionRequestHandler; namespace Service::SM { +class Controller; + /// Interface to "sm:" service class SM final : public ServiceFramework<SM> { public: @@ -32,8 +36,6 @@ private: std::shared_ptr<ServiceManager> service_manager; }; -class Controller; - constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1); constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1); constexpr ResultCode ERR_INVALID_NAME_SIZE(-1); diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 37b58bb77..2172c681b 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -80,8 +80,8 @@ public: {5, nullptr, "GetTimeZoneRuleVersion"}, {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"}, {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, - {200, nullptr, "ToPosixTime"}, - {201, nullptr, "ToPosixTimeWithMyRule"}, + {201, nullptr, "ToPosixTime"}, + {202, nullptr, "ToPosixTimeWithMyRule"}, }; RegisterHandlers(functions); } diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp new file mode 100644 index 000000000..e7fb5a419 --- /dev/null +++ b/src/core/hle/service/usb/usb.cpp @@ -0,0 +1,238 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/logging/log.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" +#include "core/hle/service/usb/usb.h" + +namespace Service::USB { + +class IDsInterface final : public ServiceFramework<IDsInterface> { +public: + explicit IDsInterface() : ServiceFramework{"IDsInterface"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetDsEndpoint"}, + {1, nullptr, "GetSetupEvent"}, + {2, nullptr, "Unknown"}, + {3, nullptr, "EnableInterface"}, + {4, nullptr, "DisableInterface"}, + {5, nullptr, "CtrlInPostBufferAsync"}, + {6, nullptr, "CtrlOutPostBufferAsync"}, + {7, nullptr, "GetCtrlInCompletionEvent"}, + {8, nullptr, "GetCtrlInReportData"}, + {9, nullptr, "GetCtrlOutCompletionEvent"}, + {10, nullptr, "GetCtrlOutReportData"}, + {11, nullptr, "StallCtrl"}, + {12, nullptr, "AppendConfigurationData"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class USB_DS final : public ServiceFramework<USB_DS> { +public: + explicit USB_DS() : ServiceFramework{"usb:ds"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "BindDevice"}, + {1, nullptr, "BindClientProcess"}, + {2, nullptr, "GetDsInterface"}, + {3, nullptr, "GetStateChangeEvent"}, + {4, nullptr, "GetState"}, + {5, nullptr, "ClearDeviceData"}, + {6, nullptr, "AddUsbStringDescriptor"}, + {7, nullptr, "DeleteUsbStringDescriptor"}, + {8, nullptr, "SetUsbDeviceDescriptor"}, + {9, nullptr, "SetBinaryObjectStore"}, + {10, nullptr, "Enable"}, + {11, nullptr, "Disable"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IClientEpSession final : public ServiceFramework<IClientEpSession> { +public: + explicit IClientEpSession() : ServiceFramework{"IClientEpSession"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "PostBufferAsync"}, + {5, nullptr, "Unknown5"}, + {6, nullptr, "Unknown6"}, + {7, nullptr, "Unknown7"}, + {8, nullptr, "Unknown8"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IClientIfSession final : public ServiceFramework<IClientIfSession> { +public: + explicit IClientIfSession() : ServiceFramework{"IClientIfSession"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "Unknown5"}, + {5, nullptr, "CtrlXferAsync"}, + {6, nullptr, "Unknown6"}, + {7, nullptr, "GetCtrlXferReport"}, + {8, nullptr, "Unknown7"}, + {9, nullptr, "GetClientEpSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class USB_HS final : public ServiceFramework<USB_HS> { +public: + explicit USB_HS() : ServiceFramework{"usb:hs"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "BindClientProcess"}, + {1, nullptr, "Unknown1"}, + {2, nullptr, "Unknown2"}, + {3, nullptr, "Unknown3"}, + {4, nullptr, "Unknown4"}, + {5, nullptr, "Unknown5"}, + {6, nullptr, "GetInterfaceStateChangeEvent"}, + {7, nullptr, "GetClientIfSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class IPdSession final : public ServiceFramework<IPdSession> { +public: + explicit IPdSession() : ServiceFramework{"IPdSession"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "BindNoticeEvent"}, + {1, nullptr, "Unknown1"}, + {2, nullptr, "GetStatus"}, + {3, nullptr, "GetNotice"}, + {4, nullptr, "Unknown2"}, + {5, nullptr, "Unknown3"}, + {6, nullptr, "ReplyPowerRequest"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class USB_PD final : public ServiceFramework<USB_PD> { +public: + explicit USB_PD() : ServiceFramework{"usb:pd"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &USB_PD::GetPdSession, "GetPdSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void GetPdSession(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IPdSession>(); + + LOG_DEBUG(Service_USB, "called"); + } +}; + +class IPdCradleSession final : public ServiceFramework<IPdCradleSession> { +public: + explicit IPdCradleSession() : ServiceFramework{"IPdCradleSession"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "VdmUserWrite"}, + {1, nullptr, "VdmUserRead"}, + {2, nullptr, "Vdm20Init"}, + {3, nullptr, "GetFwType"}, + {4, nullptr, "GetFwRevision"}, + {5, nullptr, "GetManufacturerId"}, + {6, nullptr, "GetDeviceId"}, + {7, nullptr, "Unknown1"}, + {8, nullptr, "Unknown2"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class USB_PD_C final : public ServiceFramework<USB_PD_C> { +public: + explicit USB_PD_C() : ServiceFramework{"usb:pd:c"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &USB_PD_C::GetPdCradleSession, "GetPdCradleSession"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void GetPdCradleSession(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IPdCradleSession>(); + + LOG_DEBUG(Service_USB, "called"); + } +}; + +class USB_PM final : public ServiceFramework<USB_PM> { +public: + explicit USB_PM() : ServiceFramework{"usb:pm"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "Unknown5"}, + {5, nullptr, "Unknown6"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<USB_DS>()->InstallAsService(sm); + std::make_shared<USB_HS>()->InstallAsService(sm); + std::make_shared<USB_PD>()->InstallAsService(sm); + std::make_shared<USB_PD_C>()->InstallAsService(sm); + std::make_shared<USB_PM>()->InstallAsService(sm); +} + +} // namespace Service::USB diff --git a/src/core/hle/service/usb/usb.h b/src/core/hle/service/usb/usb.h new file mode 100644 index 000000000..970a11fe8 --- /dev/null +++ b/src/core/hle/service/usb/usb.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::USB { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::USB diff --git a/src/core/hle/service/wlan/wlan.cpp b/src/core/hle/service/wlan/wlan.cpp new file mode 100644 index 000000000..2654594c1 --- /dev/null +++ b/src/core/hle/service/wlan/wlan.cpp @@ -0,0 +1,172 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h" +#include "core/hle/service/wlan/wlan.h" + +namespace Service::WLAN { + +class WLANInfra final : public ServiceFramework<WLANInfra> { +public: + explicit WLANInfra() : ServiceFramework{"wlan:inf"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "GetMacAddress"}, + {3, nullptr, "StartScan"}, + {4, nullptr, "StopScan"}, + {5, nullptr, "Connect"}, + {6, nullptr, "CancelConnect"}, + {7, nullptr, "Disconnect"}, + {8, nullptr, "Unknown3"}, + {9, nullptr, "Unknown4"}, + {10, nullptr, "GetState"}, + {11, nullptr, "GetScanResult"}, + {12, nullptr, "GetRssi"}, + {13, nullptr, "ChangeRxAntenna"}, + {14, nullptr, "Unknown5"}, + {15, nullptr, "Unknown6"}, + {16, nullptr, "RequestWakeUp"}, + {17, nullptr, "RequestIfUpDown"}, + {18, nullptr, "Unknown7"}, + {19, nullptr, "Unknown8"}, + {20, nullptr, "Unknown9"}, + {21, nullptr, "Unknown10"}, + {22, nullptr, "Unknown11"}, + {23, nullptr, "Unknown12"}, + {24, nullptr, "Unknown13"}, + {25, nullptr, "Unknown14"}, + {26, nullptr, "Unknown15"}, + {27, nullptr, "Unknown16"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class WLANLocal final : public ServiceFramework<WLANLocal> { +public: + explicit WLANLocal() : ServiceFramework{"wlan:lcl"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "Unknown5"}, + {5, nullptr, "Unknown6"}, + {6, nullptr, "GetMacAddress"}, + {7, nullptr, "CreateBss"}, + {8, nullptr, "DestroyBss"}, + {9, nullptr, "StartScan"}, + {10, nullptr, "StopScan"}, + {11, nullptr, "Connect"}, + {12, nullptr, "CancelConnect"}, + {13, nullptr, "Join"}, + {14, nullptr, "CancelJoin"}, + {15, nullptr, "Disconnect"}, + {16, nullptr, "SetBeaconLostCount"}, + {17, nullptr, "Unknown7"}, + {18, nullptr, "Unknown8"}, + {19, nullptr, "Unknown9"}, + {20, nullptr, "GetBssIndicationEvent"}, + {21, nullptr, "GetBssIndicationInfo"}, + {22, nullptr, "GetState"}, + {23, nullptr, "GetAllowedChannels"}, + {24, nullptr, "AddIe"}, + {25, nullptr, "DeleteIe"}, + {26, nullptr, "Unknown10"}, + {27, nullptr, "Unknown11"}, + {28, nullptr, "CreateRxEntry"}, + {29, nullptr, "DeleteRxEntry"}, + {30, nullptr, "Unknown12"}, + {31, nullptr, "Unknown13"}, + {32, nullptr, "AddMatchingDataToRxEntry"}, + {33, nullptr, "RemoveMatchingDataFromRxEntry"}, + {34, nullptr, "GetScanResult"}, + {35, nullptr, "Unknown14"}, + {36, nullptr, "SetActionFrameWithBeacon"}, + {37, nullptr, "CancelActionFrameWithBeacon"}, + {38, nullptr, "CreateRxEntryForActionFrame"}, + {39, nullptr, "DeleteRxEntryForActionFrame"}, + {40, nullptr, "Unknown15"}, + {41, nullptr, "Unknown16"}, + {42, nullptr, "CancelGetActionFrame"}, + {43, nullptr, "GetRssi"}, + {44, nullptr, "Unknown17"}, + {45, nullptr, "Unknown18"}, + {46, nullptr, "Unknown19"}, + {47, nullptr, "Unknown20"}, + {48, nullptr, "Unknown21"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class WLANLocalGetFrame final : public ServiceFramework<WLANLocalGetFrame> { +public: + explicit WLANLocalGetFrame() : ServiceFramework{"wlan:lg"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class WLANSocketGetFrame final : public ServiceFramework<WLANSocketGetFrame> { +public: + explicit WLANSocketGetFrame() : ServiceFramework{"wlan:sg"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class WLANSocketManager final : public ServiceFramework<WLANSocketManager> { +public: + explicit WLANSocketManager() : ServiceFramework{"wlan:soc"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Unknown1"}, + {1, nullptr, "Unknown2"}, + {2, nullptr, "Unknown3"}, + {3, nullptr, "Unknown4"}, + {4, nullptr, "Unknown5"}, + {5, nullptr, "Unknown6"}, + {6, nullptr, "GetMacAddress"}, + {7, nullptr, "SwitchTsfTimerFunction"}, + {8, nullptr, "Unknown7"}, + {9, nullptr, "Unknown8"}, + {10, nullptr, "Unknown9"}, + {11, nullptr, "Unknown10"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +void InstallInterfaces(SM::ServiceManager& sm) { + std::make_shared<WLANInfra>()->InstallAsService(sm); + std::make_shared<WLANLocal>()->InstallAsService(sm); + std::make_shared<WLANLocalGetFrame>()->InstallAsService(sm); + std::make_shared<WLANSocketGetFrame>()->InstallAsService(sm); + std::make_shared<WLANSocketManager>()->InstallAsService(sm); +} + +} // namespace Service::WLAN diff --git a/src/core/hle/service/wlan/wlan.h b/src/core/hle/service/wlan/wlan.h new file mode 100644 index 000000000..054ea928a --- /dev/null +++ b/src/core/hle/service/wlan/wlan.h @@ -0,0 +1,15 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service::SM { +class ServiceManager; +} + +namespace Service::WLAN { + +void InstallInterfaces(SM::ServiceManager& sm); + +} // namespace Service::WLAN |