mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-22 13:59:18 +01:00
libNX Time Initalization
What was added: * Time service * CNTPCT_EL0 redirected to CNTVCT_EL0
This commit is contained in:
parent
2476c5d48a
commit
e44809355c
@ -34,6 +34,7 @@ add_library(skyline SHARED
|
|||||||
${source_DIR}/skyline/kernel/services/apm/apm.cpp
|
${source_DIR}/skyline/kernel/services/apm/apm.cpp
|
||||||
${source_DIR}/skyline/kernel/services/am/appletOE.cpp
|
${source_DIR}/skyline/kernel/services/am/appletOE.cpp
|
||||||
${source_DIR}/skyline/kernel/services/hid/hid.cpp
|
${source_DIR}/skyline/kernel/services/hid/hid.cpp
|
||||||
|
${source_DIR}/skyline/kernel/services/time/time.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(skyline fmt tinyxml2)
|
target_link_libraries(skyline fmt tinyxml2)
|
||||||
target_compile_options(skyline PRIVATE -Wno-c++17-extensions)
|
target_compile_options(skyline PRIVATE -Wno-c++17-extensions)
|
||||||
|
@ -49,6 +49,8 @@ namespace skyline {
|
|||||||
constexpr u16 SvcLast = 0x7F; //!< The index of the last SVC
|
constexpr u16 SvcLast = 0x7F; //!< The index of the last SVC
|
||||||
constexpr u16 BrkRdy = 0xFF; //!< This is reserved for our kernel's to know when a process/thread is ready
|
constexpr u16 BrkRdy = 0xFF; //!< This is reserved for our kernel's to know when a process/thread is ready
|
||||||
constexpr u32 TpidrroEl0 = 0x5E83; //!< ID of TPIDRRO_EL0 in MRS
|
constexpr u32 TpidrroEl0 = 0x5E83; //!< ID of TPIDRRO_EL0 in MRS
|
||||||
|
constexpr u32 CntpctEl0 = 0x5F01; //!< ID of CNTPCT_EL0 in MRS
|
||||||
|
constexpr u32 CntvctEl0 = 0x5F02; //!< ID of CNTVCT_EL0 in MRS
|
||||||
// Kernel
|
// Kernel
|
||||||
constexpr u64 MaxSyncHandles = 0x40; //!< The total amount of handles that can be passed to WaitSynchronization
|
constexpr u64 MaxSyncHandles = 0x40; //!< The total amount of handles that can be passed to WaitSynchronization
|
||||||
constexpr handle_t BaseHandleIndex = 0xD000; // The index of the base handle
|
constexpr handle_t BaseHandleIndex = 0xD000; // The index of the base handle
|
||||||
@ -82,13 +84,13 @@ namespace skyline {
|
|||||||
*/
|
*/
|
||||||
struct Brk {
|
struct Brk {
|
||||||
/**
|
/**
|
||||||
* Creates a BRK instruction with a specific immediate value, used for generating BRK opcodes
|
* @brief Creates a BRK instruction with a specific immediate value, used for generating BRK opcodes
|
||||||
* @param val The immediate value of the instruction
|
* @param val The immediate value of the instruction
|
||||||
*/
|
*/
|
||||||
Brk(u16 val) {
|
Brk(u16 val) {
|
||||||
start = 0x0; // First 5 bits of an BRK instruction are 0
|
start = 0x0; // First 5 bits of a BRK instruction are 0
|
||||||
value = val;
|
value = val;
|
||||||
end = 0x6A1; // Last 11 bits of an BRK instruction stored as u16
|
end = 0x6A1; // Last 11 bits of a BRK instruction stored as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,6 +131,17 @@ namespace skyline {
|
|||||||
* @brief A bit-field struct that encapsulates a MRS instruction. See https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/mrs-move-system-register.
|
* @brief A bit-field struct that encapsulates a MRS instruction. See https://developer.arm.com/docs/ddi0596/latest/base-instructions-alphabetic-order/mrs-move-system-register.
|
||||||
*/
|
*/
|
||||||
struct Mrs {
|
struct Mrs {
|
||||||
|
/**
|
||||||
|
* @brief Creates a MRS instruction, used for generating BRK opcodes
|
||||||
|
* @param srcReg The source system register
|
||||||
|
* @param dstReg The destination Xn register
|
||||||
|
*/
|
||||||
|
Mrs(u32 srcReg, u8 dstReg) {
|
||||||
|
this->srcReg = srcReg;
|
||||||
|
this->dstReg = dstReg;
|
||||||
|
end = 0xD53; // Last 12 bits of a MRS instruction stored as u16
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns if the opcode is valid or not
|
* @brief Returns if the opcode is valid or not
|
||||||
* @return If the opcode represents a valid MRS instruction
|
* @return If the opcode represents a valid MRS instruction
|
||||||
|
@ -180,7 +180,7 @@ namespace skyline::kernel::service::am {
|
|||||||
IApplicationFunctions(const DeviceState &state, ServiceManager &manager);
|
IApplicationFunctions(const DeviceState &state, ServiceManager &manager);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This just returns 1 regardless of input (https://switchbrew.org/wiki/Applet_Manager_services#NotifyRunning)
|
* @brief This just returns a boolean true (https://switchbrew.org/wiki/Applet_Manager_services#NotifyRunning)
|
||||||
*/
|
*/
|
||||||
void NotifyRunning(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
void NotifyRunning(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
};
|
};
|
||||||
|
@ -31,6 +31,9 @@ namespace skyline::kernel::service {
|
|||||||
am_IDebugFunctions,
|
am_IDebugFunctions,
|
||||||
hid,
|
hid,
|
||||||
hid_IAppletResource,
|
hid_IAppletResource,
|
||||||
|
time,
|
||||||
|
time_ISystemClock,
|
||||||
|
time_ITimeZoneService,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,6 +57,10 @@ namespace skyline::kernel::service {
|
|||||||
{"am:IDebugFunctions", Service::am_IDebugFunctions},
|
{"am:IDebugFunctions", Service::am_IDebugFunctions},
|
||||||
{"hid", Service::hid},
|
{"hid", Service::hid},
|
||||||
{"hid:IAppletResource", Service::hid_IAppletResource},
|
{"hid:IAppletResource", Service::hid_IAppletResource},
|
||||||
|
{"time:s", Service::time},
|
||||||
|
{"time:a", Service::time},
|
||||||
|
{"time:ISystemClock", Service::time_ISystemClock},
|
||||||
|
{"time:ITimeZoneService", Service::time_ITimeZoneService},
|
||||||
};
|
};
|
||||||
|
|
||||||
class ServiceManager;
|
class ServiceManager;
|
||||||
|
@ -23,7 +23,8 @@ namespace skyline::kernel::service::hid {
|
|||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
void hid::CreateAppletResource(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
void hid::CreateAppletResource(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
resource = std::static_pointer_cast<IAppletResource>(manager.NewService(Service::hid_IAppletResource, session, response));
|
resource = std::make_shared<IAppletResource>(state, manager);
|
||||||
|
manager.RegisterService(resource, session, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hid::SetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
void hid::SetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "am/appletOE.h"
|
#include "am/appletOE.h"
|
||||||
#include "fatal/fatal.h"
|
#include "fatal/fatal.h"
|
||||||
#include "hid/hid.h"
|
#include "hid/hid.h"
|
||||||
|
#include "time/timesrv.h"
|
||||||
|
|
||||||
namespace skyline::kernel::service {
|
namespace skyline::kernel::service {
|
||||||
ServiceManager::ServiceManager(const DeviceState &state) : state(state) {}
|
ServiceManager::ServiceManager(const DeviceState &state) : state(state) {}
|
||||||
@ -13,64 +14,69 @@ namespace skyline::kernel::service {
|
|||||||
std::shared_ptr<BaseService> ServiceManager::GetService(const Service serviceType) {
|
std::shared_ptr<BaseService> ServiceManager::GetService(const Service serviceType) {
|
||||||
std::shared_ptr<BaseService> serviceObj;
|
std::shared_ptr<BaseService> serviceObj;
|
||||||
switch (serviceType) {
|
switch (serviceType) {
|
||||||
case Service::sm:
|
case Service::sm:
|
||||||
serviceObj = std::make_shared<sm::sm>(state, *this);
|
serviceObj = std::make_shared<sm::sm>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::fatal_u:
|
case Service::fatal_u:
|
||||||
serviceObj = std::make_shared<fatal::fatalU>(state, *this);
|
serviceObj = std::make_shared<fatal::fatalU>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::set_sys:
|
case Service::set_sys:
|
||||||
serviceObj = std::make_shared<set::sys>(state, *this);
|
serviceObj = std::make_shared<set::sys>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::apm:
|
case Service::apm:
|
||||||
serviceObj = std::make_shared<apm::apm>(state, *this);
|
serviceObj = std::make_shared<apm::apm>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::apm_ISession:
|
case Service::apm_ISession:
|
||||||
serviceObj = std::make_shared<apm::ISession>(state, *this);
|
serviceObj = std::make_shared<apm::ISession>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_appletOE:
|
case Service::am_appletOE:
|
||||||
serviceObj = std::make_shared<am::appletOE>(state, *this);
|
serviceObj = std::make_shared<am::appletOE>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_IApplicationProxy:
|
case Service::am_IApplicationProxy:
|
||||||
serviceObj = std::make_shared<am::IApplicationProxy>(state, *this);
|
serviceObj = std::make_shared<am::IApplicationProxy>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_ICommonStateGetter:
|
case Service::am_ICommonStateGetter:
|
||||||
serviceObj = std::make_shared<am::ICommonStateGetter>(state, *this);
|
serviceObj = std::make_shared<am::ICommonStateGetter>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_IWindowController:
|
case Service::am_IWindowController:
|
||||||
serviceObj = std::make_shared<am::IWindowController>(state, *this);
|
serviceObj = std::make_shared<am::IWindowController>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_IAudioController:
|
case Service::am_IAudioController:
|
||||||
serviceObj = std::make_shared<am::IAudioController>(state, *this);
|
serviceObj = std::make_shared<am::IAudioController>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_IDisplayController:
|
case Service::am_IDisplayController:
|
||||||
serviceObj = std::make_shared<am::IDisplayController>(state, *this);
|
serviceObj = std::make_shared<am::IDisplayController>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_ISelfController:
|
case Service::am_ISelfController:
|
||||||
serviceObj = std::make_shared<am::ISelfController>(state, *this);
|
serviceObj = std::make_shared<am::ISelfController>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_ILibraryAppletCreator:
|
case Service::am_ILibraryAppletCreator:
|
||||||
serviceObj = std::make_shared<am::ILibraryAppletCreator>(state, *this);
|
serviceObj = std::make_shared<am::ILibraryAppletCreator>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_IApplicationFunctions:
|
case Service::am_IApplicationFunctions:
|
||||||
serviceObj = std::make_shared<am::IApplicationFunctions>(state, *this);
|
serviceObj = std::make_shared<am::IApplicationFunctions>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::am_IDebugFunctions:
|
case Service::am_IDebugFunctions:
|
||||||
serviceObj = std::make_shared<am::IDebugFunctions>(state, *this);
|
serviceObj = std::make_shared<am::IDebugFunctions>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::hid:
|
case Service::hid:
|
||||||
serviceObj = std::make_shared<hid::hid>(state, *this);
|
serviceObj = std::make_shared<hid::hid>(state, *this);
|
||||||
break;
|
break;
|
||||||
case Service::hid_IAppletResource:
|
case Service::hid_IAppletResource:
|
||||||
serviceObj = std::make_shared<hid::IAppletResource>(state, *this);
|
serviceObj = std::make_shared<hid::IAppletResource>(state, *this);
|
||||||
break;
|
break;
|
||||||
|
case Service::time:
|
||||||
|
serviceObj = std::make_shared<time::time>(state, *this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw exception("GetService called on missing object");
|
||||||
}
|
}
|
||||||
serviceVec.push_back(serviceObj);
|
serviceVec.push_back(serviceObj);
|
||||||
return serviceObj;
|
return serviceObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_t ServiceManager::NewSession(const Service serviceType) {
|
handle_t ServiceManager::NewSession(const Service serviceType) {
|
||||||
return state.thisProcess->NewHandle<type::KSession>(GetService(serviceType), serviceType).handle;
|
return state.thisProcess->NewHandle<type::KSession>(GetService(serviceType)).handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<BaseService> ServiceManager::NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response) {
|
std::shared_ptr<BaseService> ServiceManager::NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response) {
|
||||||
@ -79,11 +85,21 @@ namespace skyline::kernel::service {
|
|||||||
session.domainTable[++session.handleIndex] = serviceObject;
|
session.domainTable[++session.handleIndex] = serviceObject;
|
||||||
response.domainObjects.push_back(session.handleIndex);
|
response.domainObjects.push_back(session.handleIndex);
|
||||||
} else
|
} else
|
||||||
response.moveHandles.push_back(state.thisProcess->NewHandle<type::KSession>(serviceObject, serviceType).handle);
|
response.moveHandles.push_back(state.thisProcess->NewHandle<type::KSession>(serviceObject).handle);
|
||||||
state.logger->Write(Logger::Debug, "Service has been registered: \"{}\"", serviceObject->getName());
|
state.logger->Write(Logger::Debug, "Service has been created: \"{}\"", serviceObject->getName());
|
||||||
return serviceObject;
|
return serviceObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServiceManager::RegisterService(std::shared_ptr<BaseService> serviceObject, type::KSession &session, ipc::IpcResponse &response) {
|
||||||
|
serviceVec.push_back(serviceObject);
|
||||||
|
if (response.isDomain) {
|
||||||
|
session.domainTable[++session.handleIndex] = serviceObject;
|
||||||
|
response.domainObjects.push_back(session.handleIndex);
|
||||||
|
} else
|
||||||
|
response.moveHandles.push_back(state.thisProcess->NewHandle<type::KSession>(serviceObject).handle);
|
||||||
|
state.logger->Write(Logger::Debug, "Service has been registered: \"{}\"", serviceObject->getName());
|
||||||
|
}
|
||||||
|
|
||||||
void ServiceManager::CloseSession(const handle_t handle) {
|
void ServiceManager::CloseSession(const handle_t handle) {
|
||||||
auto session = state.thisProcess->GetHandle<type::KSession>(handle);
|
auto session = state.thisProcess->GetHandle<type::KSession>(handle);
|
||||||
if (session->serviceStatus == type::KSession::ServiceStatus::Open) {
|
if (session->serviceStatus == type::KSession::ServiceStatus::Open) {
|
||||||
|
@ -33,13 +33,22 @@ namespace skyline::kernel::service {
|
|||||||
handle_t NewSession(const Service serviceType);
|
handle_t NewSession(const Service serviceType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new service and writes it's handle or virtual handle (If it's a domain request) to IpcResponse
|
* @brief Creates a new service using it's type enum and writes it's handle or virtual handle (If it's a domain request) to IpcResponse
|
||||||
* @param serviceType The type of the service
|
* @param serviceType The type of the service
|
||||||
* @param session The session object of the command
|
* @param session The session object of the command
|
||||||
* @param response The response object to write the handle or virtual handle to
|
* @param response The response object to write the handle or virtual handle to
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<BaseService> NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response);
|
std::shared_ptr<BaseService> NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers a service object in the manager and writes it's handle or virtual handle (If it's a domain request) to IpcResponse
|
||||||
|
* @param serviceObject An instance of the service
|
||||||
|
* @param session The session object of the command
|
||||||
|
* @param response The response object to write the handle or virtual handle to
|
||||||
|
*/
|
||||||
|
void RegisterService(std::shared_ptr<BaseService> serviceObject, type::KSession &session, ipc::IpcResponse &response);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Closes an existing session to a service
|
* @brief Closes an existing session to a service
|
||||||
* @param service The handle of the KService object
|
* @param service The handle of the KService object
|
||||||
|
59
app/src/main/cpp/skyline/kernel/services/time/time.cpp
Normal file
59
app/src/main/cpp/skyline/kernel/services/time/time.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "timesrv.h"
|
||||||
|
|
||||||
|
namespace skyline::kernel::service::time {
|
||||||
|
time::time(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, false, Service::time, {
|
||||||
|
{0x0, SFunc(time::GetStandardUserSystemClock)},
|
||||||
|
{0x1, SFunc(time::GetStandardNetworkSystemClock)},
|
||||||
|
{0x3, SFunc(time::GetTimeZoneService)},
|
||||||
|
{0x4, SFunc(time::GetStandardLocalSystemClock)}
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
void time::GetStandardUserSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
manager.RegisterService(std::make_shared<ISystemClock>(SystemClockType::User, state, manager), session, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void time::GetStandardNetworkSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
manager.RegisterService(std::make_shared<ISystemClock>(SystemClockType::Network, state, manager), session, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void time::GetTimeZoneService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
manager.RegisterService(std::make_shared<ITimeZoneService>(state, manager), session, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void time::GetStandardLocalSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
manager.RegisterService(std::make_shared<ISystemClock>(SystemClockType::Local, state, manager), session, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
ISystemClock::ISystemClock(SystemClockType clockType, const DeviceState &state, ServiceManager &manager) : type(clockType), BaseService(state, manager, false, Service::time_ISystemClock, {
|
||||||
|
{0x0, SFunc(ISystemClock::GetCurrentTime)}
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
void ISystemClock::GetCurrentTime(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
response.WriteValue<u64>(static_cast<u64>(std::time(nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ITimeZoneService::ITimeZoneService(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, false, Service::time_ITimeZoneService, {
|
||||||
|
{0x65, SFunc(ITimeZoneService::ToCalendarTimeWithMyRule)}
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
void ITimeZoneService::ToCalendarTimeWithMyRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||||
|
time_t curTime = std::time(nullptr);
|
||||||
|
tm calender = *std::gmtime(&curTime);
|
||||||
|
CalendarTime calendarTime {
|
||||||
|
.year = static_cast<u16>(calender.tm_year),
|
||||||
|
.month = static_cast<u8>(calender.tm_mon),
|
||||||
|
.day = static_cast<u8>(calender.tm_hour),
|
||||||
|
.minute = static_cast<u8>(calender.tm_min),
|
||||||
|
.second = static_cast<u8>(calender.tm_sec)
|
||||||
|
};
|
||||||
|
response.WriteValue(calendarTime);
|
||||||
|
CalendarAdditionalInfo calendarInfo {
|
||||||
|
.day_week = static_cast<u32>(calender.tm_wday),
|
||||||
|
.day_month = static_cast<u32>(calender.tm_mday),
|
||||||
|
.name = *reinterpret_cast<const u64*>(calender.tm_zone),
|
||||||
|
.dst = static_cast<i32>(calender.tm_isdst),
|
||||||
|
.utc_rel = static_cast<u32>(calender.tm_gmtoff)
|
||||||
|
};
|
||||||
|
response.WriteValue(calendarInfo);
|
||||||
|
}
|
||||||
|
}
|
97
app/src/main/cpp/skyline/kernel/services/time/timesrv.h
Normal file
97
app/src/main/cpp/skyline/kernel/services/time/timesrv.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/services/base_service.h>
|
||||||
|
#include <kernel/services/serviceman.h>
|
||||||
|
|
||||||
|
namespace skyline::kernel::service::time {
|
||||||
|
/**
|
||||||
|
* @brief The type of a SystemClockType
|
||||||
|
*/
|
||||||
|
enum SystemClockType {
|
||||||
|
User, //!< Use time provided by user
|
||||||
|
Network, //!< Use network time
|
||||||
|
Local, //!< Use local time
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief time (This covers both time:a and time:s) is responsible for providing handles to various clock services (https://switchbrew.org/wiki/PSC_services#time:su.2C_time:s)
|
||||||
|
*/
|
||||||
|
class time : public BaseService {
|
||||||
|
public:
|
||||||
|
time(const DeviceState &state, ServiceManager& manager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This returns a handle to a ISystemClock for user time (https://switchbrew.org/wiki/Services_API#GetStandardUserSystemClock)
|
||||||
|
*/
|
||||||
|
void GetStandardUserSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This returns a handle to a ISystemClock for user time (https://switchbrew.org/wiki/Services_API#GetStandardNetworkSystemClock)
|
||||||
|
*/
|
||||||
|
void GetStandardNetworkSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This returns a handle to a ISystemClock for user time (https://switchbrew.org/wiki/Services_API#GetStandardNetworkSystemClock)
|
||||||
|
*/
|
||||||
|
void GetTimeZoneService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This returns a handle to a ISystemClock for user time (https://switchbrew.org/wiki/Services_API#GetStandardNetworkSystemClock)
|
||||||
|
*/
|
||||||
|
void GetStandardLocalSystemClock(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISystemClock is used to retrieve and set time (https://switchbrew.org/wiki/PSC_services#ISystemClock)
|
||||||
|
*/
|
||||||
|
class ISystemClock : public BaseService {
|
||||||
|
public:
|
||||||
|
SystemClockType type; //!< The type of the system clock
|
||||||
|
|
||||||
|
ISystemClock(SystemClockType clockType, const DeviceState &state, ServiceManager& manager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This returns the amount of seconds since epoch
|
||||||
|
*/
|
||||||
|
void GetCurrentTime(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ITimeZoneService is used to retrieve and set time (https://switchbrew.org/wiki/PSC_services#ITimeZoneService)
|
||||||
|
*/
|
||||||
|
class ITimeZoneService : public BaseService {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief This holds a particular time point in calendar format
|
||||||
|
*/
|
||||||
|
struct CalendarTime {
|
||||||
|
u16 year;
|
||||||
|
u8 month;
|
||||||
|
u8 day;
|
||||||
|
u8 hour;
|
||||||
|
u8 minute;
|
||||||
|
u8 second;
|
||||||
|
u8 : 8;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CalendarTime)==8);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This is passed in addition to CalendarTime
|
||||||
|
*/
|
||||||
|
struct CalendarAdditionalInfo {
|
||||||
|
u32 day_week;
|
||||||
|
u32 day_month;
|
||||||
|
u64 name;
|
||||||
|
i32 dst;
|
||||||
|
u32 utc_rel;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CalendarAdditionalInfo)==24);
|
||||||
|
|
||||||
|
ITimeZoneService(const DeviceState &state, ServiceManager& manager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This receives a u64 #PosixTime (https://switchbrew.org/wiki/PSC_services#PosixTime), and returns a #CalendarTime (https://switchbrew.org/wiki/PSC_services#CalendarTime), #CalendarAdditionalInfo (https://switchbrew.org/wiki/PSC_services#CalendarAdditionalInfo)
|
||||||
|
*/
|
||||||
|
void ToCalendarTimeWithMyRule(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||||
|
};
|
||||||
|
}
|
@ -20,9 +20,8 @@ namespace skyline::kernel::type {
|
|||||||
/**
|
/**
|
||||||
* @param state The state of the device
|
* @param state The state of the device
|
||||||
* @param serviceObject A shared pointer to the service class
|
* @param serviceObject A shared pointer to the service class
|
||||||
* @param serviceType The type of the service
|
|
||||||
*/
|
*/
|
||||||
KSession(const DeviceState &state, std::shared_ptr<service::BaseService> &serviceObject, const service::Service &serviceType) : serviceObject(serviceObject), serviceType(serviceType), KSyncObject(state, KType::KSession) {}
|
KSession(const DeviceState &state, std::shared_ptr<service::BaseService> &serviceObject) : serviceObject(serviceObject), serviceType(serviceObject->serviceType), KSyncObject(state, KType::KSession) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This converts this session into a domain session (https://switchbrew.org/wiki/IPC_Marshalling#Domains)
|
* This converts this session into a domain session (https://switchbrew.org/wiki/IPC_Marshalling#Domains)
|
||||||
|
@ -37,9 +37,14 @@ namespace skyline::loader {
|
|||||||
if (instrSvc->Verify()) {
|
if (instrSvc->Verify()) {
|
||||||
instr::Brk brk(static_cast<u16>(instrSvc->value));
|
instr::Brk brk(static_cast<u16>(instrSvc->value));
|
||||||
*address = *reinterpret_cast<u32 *>(&brk);
|
*address = *reinterpret_cast<u32 *>(&brk);
|
||||||
} else if (instrMrs->Verify() && instrMrs->srcReg == constant::TpidrroEl0) {
|
} else if (instrMrs->Verify()) {
|
||||||
instr::Brk brk(static_cast<u16>(constant::SvcLast + 1 + instrMrs->dstReg));
|
if(instrMrs->srcReg == constant::TpidrroEl0) {
|
||||||
*address = *reinterpret_cast<u32 *>(&brk);
|
instr::Brk brk(static_cast<u16>(constant::SvcLast + 1 + instrMrs->dstReg));
|
||||||
|
*address = *reinterpret_cast<u32 *>(&brk);
|
||||||
|
} else if(instrMrs->srcReg == constant::CntpctEl0) {
|
||||||
|
instr::Mrs mrs(constant::CntvctEl0, instrMrs->dstReg);
|
||||||
|
*address = *reinterpret_cast<u32 *>(&mrs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user