early-access version 2835
This commit is contained in:
@@ -128,7 +128,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||
SUB(Service, PM) \
|
||||
SUB(Service, PREPO) \
|
||||
SUB(Service, PSC) \
|
||||
SUB(Service, PSM) \
|
||||
SUB(Service, PTM) \
|
||||
SUB(Service, SET) \
|
||||
SUB(Service, SM) \
|
||||
SUB(Service, SPL) \
|
||||
|
@@ -95,7 +95,7 @@ enum class Class : u8 {
|
||||
Service_PM, ///< The PM service
|
||||
Service_PREPO, ///< The PREPO (Play report) service
|
||||
Service_PSC, ///< The PSC service
|
||||
Service_PSM, ///< The PSM service
|
||||
Service_PTM, ///< The PTM service
|
||||
Service_SET, ///< The SET (Settings) service
|
||||
Service_SM, ///< The SM (Service manager) service
|
||||
Service_SPL, ///< The SPL service
|
||||
|
@@ -67,7 +67,7 @@ std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency,
|
||||
const auto& caps = GetCPUCaps();
|
||||
u64 rtsc_frequency = 0;
|
||||
if (caps.invariant_tsc) {
|
||||
rtsc_frequency = EstimateRDTSCFrequency();
|
||||
rtsc_frequency = caps.tsc_frequency ? caps.tsc_frequency : EstimateRDTSCFrequency();
|
||||
}
|
||||
|
||||
// Fallback to StandardWallClock if the hardware TSC does not have the precision greater than:
|
||||
|
@@ -161,6 +161,22 @@ static CPUCaps Detect() {
|
||||
caps.invariant_tsc = Common::Bit<8>(cpu_id[3]);
|
||||
}
|
||||
|
||||
if (max_std_fn >= 0x15) {
|
||||
__cpuid(cpu_id, 0x15);
|
||||
caps.tsc_crystal_ratio_denominator = cpu_id[0];
|
||||
caps.tsc_crystal_ratio_numerator = cpu_id[1];
|
||||
caps.crystal_frequency = cpu_id[2];
|
||||
// Some CPU models might not return a crystal frequency.
|
||||
// The CPU model can be detected to use the values from turbostat
|
||||
// https://github.com/torvalds/linux/blob/master/tools/power/x86/turbostat/turbostat.c#L5569
|
||||
// but it's easier to just estimate the TSC tick rate for these cases.
|
||||
if (caps.tsc_crystal_ratio_denominator) {
|
||||
caps.tsc_frequency = static_cast<u64>(caps.crystal_frequency) *
|
||||
caps.tsc_crystal_ratio_numerator /
|
||||
caps.tsc_crystal_ratio_denominator;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_std_fn >= 0x16) {
|
||||
__cpuid(cpu_id, 0x16);
|
||||
caps.base_frequency = cpu_id[0];
|
||||
|
@@ -30,6 +30,11 @@ struct CPUCaps {
|
||||
u32 max_frequency;
|
||||
u32 bus_frequency;
|
||||
|
||||
u32 tsc_crystal_ratio_denominator;
|
||||
u32 tsc_crystal_ratio_numerator;
|
||||
u32 crystal_frequency;
|
||||
u64 tsc_frequency; // Derived from the above three values
|
||||
|
||||
bool sse : 1;
|
||||
bool sse2 : 1;
|
||||
bool sse3 : 1;
|
||||
|
@@ -607,6 +607,10 @@ add_library(core STATIC
|
||||
hle/service/psc/psc.h
|
||||
hle/service/ptm/psm.cpp
|
||||
hle/service/ptm/psm.h
|
||||
hle/service/ptm/ptm.cpp
|
||||
hle/service/ptm/ptm.h
|
||||
hle/service/ptm/ts.cpp
|
||||
hle/service/ptm/ts.h
|
||||
hle/service/kernel_helpers.cpp
|
||||
hle/service/kernel_helpers.h
|
||||
hle/service/service.cpp
|
||||
|
@@ -290,7 +290,7 @@ protected:
|
||||
void Get(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_ACC, "called user_id=0x{}", user_id.RawString());
|
||||
ProfileBase profile_base{};
|
||||
ProfileData data{};
|
||||
UserData data{};
|
||||
if (profile_manager.GetProfileBaseAndData(user_id, profile_base, data)) {
|
||||
ctx.WriteBuffer(data);
|
||||
IPC::ResponseBuilder rb{ctx, 16};
|
||||
@@ -373,18 +373,18 @@ protected:
|
||||
reinterpret_cast<const char*>(base.username.data()), base.username.size()),
|
||||
base.timestamp, base.user_uuid.RawString());
|
||||
|
||||
if (user_data.size() < sizeof(ProfileData)) {
|
||||
LOG_ERROR(Service_ACC, "ProfileData buffer too small!");
|
||||
if (user_data.size() < sizeof(UserData)) {
|
||||
LOG_ERROR(Service_ACC, "UserData buffer too small!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_INVALID_BUFFER);
|
||||
return;
|
||||
}
|
||||
|
||||
ProfileData data;
|
||||
std::memcpy(&data, user_data.data(), sizeof(ProfileData));
|
||||
UserData data;
|
||||
std::memcpy(&data, user_data.data(), sizeof(UserData));
|
||||
|
||||
if (!profile_manager.SetProfileBaseAndData(user_id, base, data)) {
|
||||
LOG_ERROR(Service_ACC, "Failed to update profile data and base!");
|
||||
LOG_ERROR(Service_ACC, "Failed to update user data and base!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_FAILED_SAVE_DATA);
|
||||
return;
|
||||
@@ -406,15 +406,15 @@ protected:
|
||||
reinterpret_cast<const char*>(base.username.data()), base.username.size()),
|
||||
base.timestamp, base.user_uuid.RawString());
|
||||
|
||||
if (user_data.size() < sizeof(ProfileData)) {
|
||||
LOG_ERROR(Service_ACC, "ProfileData buffer too small!");
|
||||
if (user_data.size() < sizeof(UserData)) {
|
||||
LOG_ERROR(Service_ACC, "UserData buffer too small!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ERR_INVALID_BUFFER);
|
||||
return;
|
||||
}
|
||||
|
||||
ProfileData data;
|
||||
std::memcpy(&data, user_data.data(), sizeof(ProfileData));
|
||||
UserData data;
|
||||
std::memcpy(&data, user_data.data(), sizeof(UserData));
|
||||
|
||||
Common::FS::IOFile image(GetImagePath(user_id), Common::FS::FileAccessMode::Write,
|
||||
Common::FS::FileType::BinaryFile);
|
||||
|
@@ -22,7 +22,7 @@ struct UserRaw {
|
||||
UUID uuid2{};
|
||||
u64 timestamp{};
|
||||
ProfileUsername username{};
|
||||
ProfileData extra_data{};
|
||||
UserData extra_data{};
|
||||
};
|
||||
static_assert(sizeof(UserRaw) == 0xC8, "UserRaw has incorrect size.");
|
||||
|
||||
@@ -263,7 +263,7 @@ UUID ProfileManager::GetLastOpenedUser() const {
|
||||
|
||||
/// Return the users profile base and the unknown arbitary data.
|
||||
bool ProfileManager::GetProfileBaseAndData(std::optional<std::size_t> index, ProfileBase& profile,
|
||||
ProfileData& data) const {
|
||||
UserData& data) const {
|
||||
if (GetProfileBase(index, profile)) {
|
||||
data = profiles[*index].data;
|
||||
return true;
|
||||
@@ -272,15 +272,14 @@ bool ProfileManager::GetProfileBaseAndData(std::optional<std::size_t> index, Pro
|
||||
}
|
||||
|
||||
/// Return the users profile base and the unknown arbitary data.
|
||||
bool ProfileManager::GetProfileBaseAndData(UUID uuid, ProfileBase& profile,
|
||||
ProfileData& data) const {
|
||||
bool ProfileManager::GetProfileBaseAndData(UUID uuid, ProfileBase& profile, UserData& data) const {
|
||||
const auto idx = GetUserIndex(uuid);
|
||||
return GetProfileBaseAndData(idx, profile, data);
|
||||
}
|
||||
|
||||
/// Return the users profile base and the unknown arbitary data.
|
||||
bool ProfileManager::GetProfileBaseAndData(const ProfileInfo& user, ProfileBase& profile,
|
||||
ProfileData& data) const {
|
||||
UserData& data) const {
|
||||
return GetProfileBaseAndData(user.user_uuid, profile, data);
|
||||
}
|
||||
|
||||
@@ -318,7 +317,7 @@ bool ProfileManager::SetProfileBase(UUID uuid, const ProfileBase& profile_new) {
|
||||
}
|
||||
|
||||
bool ProfileManager::SetProfileBaseAndData(Common::UUID uuid, const ProfileBase& profile_new,
|
||||
const ProfileData& data_new) {
|
||||
const UserData& data_new) {
|
||||
const auto index = GetUserIndex(uuid);
|
||||
if (index.has_value() && SetProfileBase(uuid, profile_new)) {
|
||||
profiles[*index].data = data_new;
|
||||
|
@@ -22,7 +22,7 @@ using UserIDArray = std::array<Common::UUID, MAX_USERS>;
|
||||
|
||||
/// Contains extra data related to a user.
|
||||
/// TODO: RE this structure
|
||||
struct ProfileData {
|
||||
struct UserData {
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u32 icon_id;
|
||||
u8 bg_color_id;
|
||||
@@ -30,7 +30,7 @@ struct ProfileData {
|
||||
INSERT_PADDING_BYTES_NOINIT(0x10);
|
||||
INSERT_PADDING_BYTES_NOINIT(0x60);
|
||||
};
|
||||
static_assert(sizeof(ProfileData) == 0x80, "ProfileData structure has incorrect size");
|
||||
static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size");
|
||||
|
||||
/// This holds general information about a users profile. This is where we store all the information
|
||||
/// based on a specific user
|
||||
@@ -38,7 +38,7 @@ struct ProfileInfo {
|
||||
Common::UUID user_uuid{};
|
||||
ProfileUsername username{};
|
||||
u64 creation_time{};
|
||||
ProfileData data{}; // TODO(ognik): Work out what this is
|
||||
UserData data{}; // TODO(ognik): Work out what this is
|
||||
bool is_open{};
|
||||
};
|
||||
|
||||
@@ -74,10 +74,9 @@ public:
|
||||
bool GetProfileBase(Common::UUID uuid, ProfileBase& profile) const;
|
||||
bool GetProfileBase(const ProfileInfo& user, ProfileBase& profile) const;
|
||||
bool GetProfileBaseAndData(std::optional<std::size_t> index, ProfileBase& profile,
|
||||
ProfileData& data) const;
|
||||
bool GetProfileBaseAndData(Common::UUID uuid, ProfileBase& profile, ProfileData& data) const;
|
||||
bool GetProfileBaseAndData(const ProfileInfo& user, ProfileBase& profile,
|
||||
ProfileData& data) const;
|
||||
UserData& data) const;
|
||||
bool GetProfileBaseAndData(Common::UUID uuid, ProfileBase& profile, UserData& data) const;
|
||||
bool GetProfileBaseAndData(const ProfileInfo& user, ProfileBase& profile, UserData& data) const;
|
||||
std::size_t GetUserCount() const;
|
||||
std::size_t GetOpenUserCount() const;
|
||||
bool UserExists(Common::UUID uuid) const;
|
||||
@@ -93,7 +92,7 @@ public:
|
||||
bool RemoveUser(Common::UUID uuid);
|
||||
bool SetProfileBase(Common::UUID uuid, const ProfileBase& profile_new);
|
||||
bool SetProfileBaseAndData(Common::UUID uuid, const ProfileBase& profile_new,
|
||||
const ProfileData& data_new);
|
||||
const UserData& data_new);
|
||||
|
||||
private:
|
||||
void ParseUserSaveFile();
|
||||
|
@@ -237,6 +237,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
|
||||
{130, nullptr, "FriendInvitationSetApplicationParameter"},
|
||||
{131, nullptr, "FriendInvitationClearApplicationParameter"},
|
||||
{132, nullptr, "FriendInvitationPushApplicationParameter"},
|
||||
{140, nullptr, "RestrictPowerOperationForSecureLaunchModeForDebug"},
|
||||
{900, nullptr, "GetGrcProcessLaunchedSystemEvent"},
|
||||
};
|
||||
// clang-format on
|
||||
@@ -1316,6 +1317,8 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
|
||||
{33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"},
|
||||
{34, nullptr, "SelectApplicationLicense"},
|
||||
{35, nullptr, "GetDeviceSaveDataSizeMax"},
|
||||
{36, nullptr, "GetLimitedApplicationLicense"},
|
||||
{37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
|
||||
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
|
||||
{50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
|
||||
{60, nullptr, "SetMediaPlaybackStateForApplication"},
|
||||
|
@@ -140,8 +140,8 @@ public:
|
||||
{20401, nullptr, "UnregisterSystemApplicationDeliveryTask"},
|
||||
{20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"},
|
||||
{30100, &IBcatService::SetPassphrase, "SetPassphrase"},
|
||||
{30101, nullptr, "Unknown"},
|
||||
{30102, nullptr, "Unknown2"},
|
||||
{30101, nullptr, "Unknown30101"},
|
||||
{30102, nullptr, "Unknown30102"},
|
||||
{30200, nullptr, "RegisterBackgroundDeliveryTask"},
|
||||
{30201, nullptr, "UnregisterBackgroundDeliveryTask"},
|
||||
{30202, nullptr, "BlockDeliveryTask"},
|
||||
|
@@ -181,6 +181,11 @@ public:
|
||||
{147, nullptr, "RegisterAudioControlNotification"},
|
||||
{148, nullptr, "SendAudioControlPassthroughCommand"},
|
||||
{149, nullptr, "SendAudioControlSetAbsoluteVolumeCommand"},
|
||||
{150, nullptr, "AcquireAudioSinkVolumeLocallyChangedEvent"},
|
||||
{151, nullptr, "AcquireAudioSinkVolumeUpdateRequestCompletedEvent"},
|
||||
{152, nullptr, "GetAudioSinkVolume"},
|
||||
{153, nullptr, "RequestUpdateAudioSinkVolume"},
|
||||
{154, nullptr, "IsAudioSinkVolumeSupported"},
|
||||
{256, nullptr, "IsManufacturingMode"},
|
||||
{257, nullptr, "EmulateBluetoothCrash"},
|
||||
{258, nullptr, "GetBleChannelMap"},
|
||||
|
@@ -214,8 +214,12 @@ public:
|
||||
{76, nullptr, "Unknown76"},
|
||||
{100, nullptr, "Unknown100"},
|
||||
{101, nullptr, "Unknown101"},
|
||||
{110, nullptr, "Unknown102"},
|
||||
{111, nullptr, "Unknown103"},
|
||||
{110, nullptr, "Unknown110"},
|
||||
{111, nullptr, "Unknown111"},
|
||||
{112, nullptr, "Unknown112"},
|
||||
{113, nullptr, "Unknown113"},
|
||||
{114, nullptr, "Unknown114"},
|
||||
{115, nullptr, "Unknown115"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
@@ -6,7 +6,13 @@
|
||||
namespace Service::Fatal {
|
||||
|
||||
Fatal_P::Fatal_P(std::shared_ptr<Module> module_, Core::System& system_)
|
||||
: Interface(std::move(module_), system_, "fatal:p") {}
|
||||
: Interface(std::move(module_), system_, "fatal:p") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetFatalEvent"},
|
||||
{10, nullptr, "GetFatalContext"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
Fatal_P::~Fatal_P() = default;
|
||||
|
||||
|
@@ -30,6 +30,19 @@ enum class RequestState : u32 {
|
||||
Connected = 3,
|
||||
};
|
||||
|
||||
enum class InternetConnectionType : u8 {
|
||||
WiFi = 1,
|
||||
Ethernet = 2,
|
||||
};
|
||||
|
||||
enum class InternetConnectionStatus : u8 {
|
||||
ConnectingUnknown1,
|
||||
ConnectingUnknown2,
|
||||
ConnectingUnknown3,
|
||||
ConnectingUnknown4,
|
||||
Connected,
|
||||
};
|
||||
|
||||
struct IpAddressSetting {
|
||||
bool is_automatic{};
|
||||
Network::IPv4Address current_address{};
|
||||
@@ -271,6 +284,7 @@ private:
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u64>(client_id); // Client ID needs to be non zero otherwise it's considered invalid
|
||||
}
|
||||
|
||||
void CreateScanRequest(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
|
||||
@@ -279,6 +293,7 @@ private:
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushIpcInterface<IScanRequest>(system);
|
||||
}
|
||||
|
||||
void CreateRequest(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
|
||||
@@ -287,6 +302,7 @@ private:
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushIpcInterface<IRequest>(system);
|
||||
}
|
||||
|
||||
void GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
@@ -335,12 +351,14 @@ private:
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void GetCurrentIpAddress(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
@@ -354,6 +372,7 @@ private:
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw(*ipv4);
|
||||
}
|
||||
|
||||
void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
|
||||
@@ -369,6 +388,7 @@ private:
|
||||
rb.PushIpcInterface<INetworkProfile>(system);
|
||||
rb.PushRaw<u128>(uuid);
|
||||
}
|
||||
|
||||
void GetCurrentIpConfigInfo(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
@@ -405,6 +425,7 @@ private:
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw<IpConfigInfo>(ip_config_info);
|
||||
}
|
||||
|
||||
void IsWirelessCommunicationEnabled(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
@@ -412,6 +433,24 @@ private:
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u8>(0);
|
||||
}
|
||||
|
||||
void GetInternetConnectionStatus(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
struct Output {
|
||||
InternetConnectionType type{InternetConnectionType::WiFi};
|
||||
u8 wifi_strength{3};
|
||||
InternetConnectionStatus state{InternetConnectionStatus::Connected};
|
||||
};
|
||||
static_assert(sizeof(Output) == 0x3, "Output has incorrect size.");
|
||||
|
||||
constexpr Output out{};
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw(out);
|
||||
}
|
||||
|
||||
void IsEthernetCommunicationEnabled(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
@@ -423,6 +462,7 @@ private:
|
||||
rb.Push<u8>(0);
|
||||
}
|
||||
}
|
||||
|
||||
void IsAnyInternetRequestAccepted(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
@@ -456,7 +496,7 @@ IGeneralService::IGeneralService(Core::System& system_)
|
||||
{15, &IGeneralService::GetCurrentIpConfigInfo, "GetCurrentIpConfigInfo"},
|
||||
{16, nullptr, "SetWirelessCommunicationEnabled"},
|
||||
{17, &IGeneralService::IsWirelessCommunicationEnabled, "IsWirelessCommunicationEnabled"},
|
||||
{18, nullptr, "GetInternetConnectionStatus"},
|
||||
{18, &IGeneralService::GetInternetConnectionStatus, "GetInternetConnectionStatus"},
|
||||
{19, nullptr, "SetEthernetCommunicationEnabled"},
|
||||
{20, &IGeneralService::IsEthernetCommunicationEnabled, "IsEthernetCommunicationEnabled"},
|
||||
{21, &IGeneralService::IsAnyInternetRequestAccepted, "IsAnyInternetRequestAccepted"},
|
||||
|
@@ -9,10 +9,8 @@
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/kernel_helpers.h"
|
||||
#include "core/hle/service/ptm/psm.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
|
||||
namespace Service::PSM {
|
||||
namespace Service::PTM {
|
||||
|
||||
class IPsmSession final : public ServiceFramework<IPsmSession> {
|
||||
public:
|
||||
@@ -57,7 +55,7 @@ public:
|
||||
|
||||
private:
|
||||
void BindStateChangeEvent(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PSM, "called");
|
||||
LOG_DEBUG(Service_PTM, "called");
|
||||
|
||||
should_signal = true;
|
||||
|
||||
@@ -67,7 +65,7 @@ private:
|
||||
}
|
||||
|
||||
void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PSM, "called");
|
||||
LOG_DEBUG(Service_PTM, "called");
|
||||
|
||||
should_signal = false;
|
||||
|
||||
@@ -78,7 +76,7 @@ private:
|
||||
void SetChargerTypeChangeEventEnabled(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto state = rp.Pop<bool>();
|
||||
LOG_DEBUG(Service_PSM, "called, state={}", state);
|
||||
LOG_DEBUG(Service_PTM, "called, state={}", state);
|
||||
|
||||
should_signal_charger_type = state;
|
||||
|
||||
@@ -89,7 +87,7 @@ private:
|
||||
void SetPowerSupplyChangeEventEnabled(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto state = rp.Pop<bool>();
|
||||
LOG_DEBUG(Service_PSM, "called, state={}", state);
|
||||
LOG_DEBUG(Service_PTM, "called, state={}", state);
|
||||
|
||||
should_signal_power_supply = state;
|
||||
|
||||
@@ -100,7 +98,7 @@ private:
|
||||
void SetBatteryVoltageStateChangeEventEnabled(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto state = rp.Pop<bool>();
|
||||
LOG_DEBUG(Service_PSM, "called, state={}", state);
|
||||
LOG_DEBUG(Service_PTM, "called, state={}", state);
|
||||
|
||||
should_signal_battery_voltage = state;
|
||||
|
||||
@@ -117,76 +115,58 @@ private:
|
||||
Kernel::KEvent* state_change_event;
|
||||
};
|
||||
|
||||
class PSM final : public ServiceFramework<PSM> {
|
||||
public:
|
||||
explicit PSM(Core::System& system_) : ServiceFramework{system_, "psm"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &PSM::GetBatteryChargePercentage, "GetBatteryChargePercentage"},
|
||||
{1, &PSM::GetChargerType, "GetChargerType"},
|
||||
{2, nullptr, "EnableBatteryCharging"},
|
||||
{3, nullptr, "DisableBatteryCharging"},
|
||||
{4, nullptr, "IsBatteryChargingEnabled"},
|
||||
{5, nullptr, "AcquireControllerPowerSupply"},
|
||||
{6, nullptr, "ReleaseControllerPowerSupply"},
|
||||
{7, &PSM::OpenSession, "OpenSession"},
|
||||
{8, nullptr, "EnableEnoughPowerChargeEmulation"},
|
||||
{9, nullptr, "DisableEnoughPowerChargeEmulation"},
|
||||
{10, nullptr, "EnableFastBatteryCharging"},
|
||||
{11, nullptr, "DisableFastBatteryCharging"},
|
||||
{12, nullptr, "GetBatteryVoltageState"},
|
||||
{13, nullptr, "GetRawBatteryChargePercentage"},
|
||||
{14, nullptr, "IsEnoughPowerSupplied"},
|
||||
{15, nullptr, "GetBatteryAgePercentage"},
|
||||
{16, nullptr, "GetBatteryChargeInfoEvent"},
|
||||
{17, nullptr, "GetBatteryChargeInfoFields"},
|
||||
{18, nullptr, "GetBatteryChargeCalibratedEvent"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
~PSM() override = default;
|
||||
|
||||
private:
|
||||
void GetBatteryChargePercentage(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PSM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u32>(battery_charge_percentage);
|
||||
}
|
||||
|
||||
void GetChargerType(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PSM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushEnum(charger_type);
|
||||
}
|
||||
|
||||
void OpenSession(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PSM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushIpcInterface<IPsmSession>(system);
|
||||
}
|
||||
|
||||
enum class ChargerType : u32 {
|
||||
Unplugged = 0,
|
||||
RegularCharger = 1,
|
||||
LowPowerCharger = 2,
|
||||
Unknown = 3,
|
||||
PSM::PSM(Core::System& system_) : ServiceFramework{system_, "psm"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &PSM::GetBatteryChargePercentage, "GetBatteryChargePercentage"},
|
||||
{1, &PSM::GetChargerType, "GetChargerType"},
|
||||
{2, nullptr, "EnableBatteryCharging"},
|
||||
{3, nullptr, "DisableBatteryCharging"},
|
||||
{4, nullptr, "IsBatteryChargingEnabled"},
|
||||
{5, nullptr, "AcquireControllerPowerSupply"},
|
||||
{6, nullptr, "ReleaseControllerPowerSupply"},
|
||||
{7, &PSM::OpenSession, "OpenSession"},
|
||||
{8, nullptr, "EnableEnoughPowerChargeEmulation"},
|
||||
{9, nullptr, "DisableEnoughPowerChargeEmulation"},
|
||||
{10, nullptr, "EnableFastBatteryCharging"},
|
||||
{11, nullptr, "DisableFastBatteryCharging"},
|
||||
{12, nullptr, "GetBatteryVoltageState"},
|
||||
{13, nullptr, "GetRawBatteryChargePercentage"},
|
||||
{14, nullptr, "IsEnoughPowerSupplied"},
|
||||
{15, nullptr, "GetBatteryAgePercentage"},
|
||||
{16, nullptr, "GetBatteryChargeInfoEvent"},
|
||||
{17, nullptr, "GetBatteryChargeInfoFields"},
|
||||
{18, nullptr, "GetBatteryChargeCalibratedEvent"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
u32 battery_charge_percentage{100}; // 100%
|
||||
ChargerType charger_type{ChargerType::RegularCharger};
|
||||
};
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
|
||||
std::make_shared<PSM>(system)->InstallAsService(sm);
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Service::PSM
|
||||
PSM::~PSM() = default;
|
||||
|
||||
void PSM::GetBatteryChargePercentage(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PTM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push<u32>(battery_charge_percentage);
|
||||
}
|
||||
|
||||
void PSM::GetChargerType(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PTM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushEnum(charger_type);
|
||||
}
|
||||
|
||||
void PSM::OpenSession(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_PTM, "called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushIpcInterface<IPsmSession>(system);
|
||||
}
|
||||
|
||||
} // namespace Service::PTM
|
||||
|
@@ -3,16 +3,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::SM {
|
||||
class ServiceManager;
|
||||
}
|
||||
namespace Service::PTM {
|
||||
|
||||
namespace Service::PSM {
|
||||
class PSM final : public ServiceFramework<PSM> {
|
||||
public:
|
||||
explicit PSM(Core::System& system_);
|
||||
~PSM() override;
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
|
||||
private:
|
||||
enum class ChargerType : u32 {
|
||||
Unplugged = 0,
|
||||
RegularCharger = 1,
|
||||
LowPowerCharger = 2,
|
||||
Unknown = 3,
|
||||
};
|
||||
|
||||
} // namespace Service::PSM
|
||||
void GetBatteryChargePercentage(Kernel::HLERequestContext& ctx);
|
||||
void GetChargerType(Kernel::HLERequestContext& ctx);
|
||||
void OpenSession(Kernel::HLERequestContext& ctx);
|
||||
|
||||
u32 battery_charge_percentage{100};
|
||||
ChargerType charger_type{ChargerType::RegularCharger};
|
||||
};
|
||||
|
||||
} // namespace Service::PTM
|
||||
|
18
src/core/hle/service/ptm/ptm.cpp
Executable file
18
src/core/hle/service/ptm/ptm.cpp
Executable file
@@ -0,0 +1,18 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/ptm/psm.h"
|
||||
#include "core/hle/service/ptm/ptm.h"
|
||||
#include "core/hle/service/ptm/ts.h"
|
||||
|
||||
namespace Service::PTM {
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
|
||||
std::make_shared<PSM>(system)->InstallAsService(sm);
|
||||
std::make_shared<TS>(system)->InstallAsService(sm);
|
||||
}
|
||||
|
||||
} // namespace Service::PTM
|
18
src/core/hle/service/ptm/ptm.h
Executable file
18
src/core/hle/service/ptm/ptm.h
Executable file
@@ -0,0 +1,18 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Service::SM {
|
||||
class ServiceManager;
|
||||
}
|
||||
|
||||
namespace Service::PTM {
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
|
||||
|
||||
} // namespace Service::PTM
|
41
src/core/hle/service/ptm/ts.cpp
Executable file
41
src/core/hle/service/ptm/ts.cpp
Executable file
@@ -0,0 +1,41 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/ptm/ts.h"
|
||||
|
||||
namespace Service::PTM {
|
||||
|
||||
TS::TS(Core::System& system_) : ServiceFramework{system_, "ts"} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetTemperatureRange"},
|
||||
{1, &TS::GetTemperature, "GetTemperature"},
|
||||
{2, nullptr, "SetMeasurementMode"},
|
||||
{3, nullptr, "GetTemperatureMilliC"},
|
||||
{4, nullptr, "OpenSession"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
TS::~TS() = default;
|
||||
|
||||
void TS::GetTemperature(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto location{rp.PopEnum<Location>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called. location={}", location);
|
||||
|
||||
const s32 temperature = location == Location::Internal ? 35 : 20;
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push(temperature);
|
||||
}
|
||||
|
||||
} // namespace Service::PTM
|
25
src/core/hle/service/ptm/ts.h
Executable file
25
src/core/hle/service/ptm/ts.h
Executable file
@@ -0,0 +1,25 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service::PTM {
|
||||
|
||||
class TS final : public ServiceFramework<TS> {
|
||||
public:
|
||||
explicit TS(Core::System& system_);
|
||||
~TS() override;
|
||||
|
||||
private:
|
||||
enum class Location : u8 {
|
||||
Internal,
|
||||
External,
|
||||
};
|
||||
|
||||
void GetTemperature(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Service::PTM
|
@@ -58,7 +58,7 @@
|
||||
#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/ptm/psm.h"
|
||||
#include "core/hle/service/ptm/ptm.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/set/settings.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
@@ -287,7 +287,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
|
||||
PlayReport::InstallInterfaces(*sm, system);
|
||||
PM::InstallInterfaces(system);
|
||||
PSC::InstallInterfaces(*sm, system);
|
||||
PSM::InstallInterfaces(*sm, system);
|
||||
PTM::InstallInterfaces(*sm, system);
|
||||
Set::InstallInterfaces(*sm, system);
|
||||
Sockets::InstallInterfaces(*sm, system);
|
||||
SPL::InstallInterfaces(*sm, system);
|
||||
|
Reference in New Issue
Block a user