SceRtc

From Vita Development Wiki
Jump to navigation Jump to search

Real Time Clock.

Module

Version World Privilege
0.931.010-3.740.011 Non-secure Kernel

Libraries

Known NIDs

Version Name World Visibility NID
0.920-3.740.011 SceRtcForDriver Non-secure Kernel 0x0351D827
0.931.010-3.740.011 SceRtc Non-secure User 0x3503487E

Types

typedef struct SceRtcTickBase { // size is 0x28-bytes
	SceRtcTick tick_src_0;
	SceRtcTick tick_dst_0;
	int unk_0x10;
	int unk_0x14;
	int tick_flags_0;
	int unk_0x1C;
	int unk_0x20;
	int unk_0x24;
} SceRtcTickBase;

// internal use. From SceRtc_data + 0x38
typedef struct SceRtcTickContext { // size is 0x140-bytes
	SceRtcTickBase current_secure_tick;
	SceRtcTickBase current_retained_network_tick;
	SceRtcTickBase current_tool_secure_tick;
	SceRtcTickBase current_gps_tick;
	SceRtcTickBase current_debug_network_tick;
	SceRtcTickBase unk_tick_5;
	SceRtcTickBase unk_tick_6;
	SceRtcTickBase unk_tick_7;
} SceRtcTickContext;

Rtc Tick

The Rtc Tick is a 64-bit integer that corresponds to the number of microseconds since 1/01/01 00:00:00.000000. A tick can be considered as the smallest unit of time usually used by PS Vita operating system and softwares.

Below are examples of Rtc Tick values and their human-readable "date-time" equivalent.

Rtc Tick DateTime
0x0000000000000000 1/01/01 00:00:00.000000
0x0000000000000001 1/01/01 00:00:00.000001
0x00000000000F4240 1/01/01 00:00:01.000000
0x0000000003938700 1/01/01 00:01:00.000000
0x00000000D693A400 1/01/01 01:00:00.000000
0x000000141DD76000 1/01/02 00:00:00.000000
0x00DCBFFEFF2BC000 1970/01/01 00:00:00.000000
0x00E2156879BFC000 2017/07/29 00:00:00.000000
0x00E2CDD60F4CE000 2024/01/01 00:00:00.000000
0x8000000000000000 30134/01/10 04:00:54.775808
0xFFFFFFFFFFFFFFFF 60267/01/19 08:01:49.551615

To convert a DateTime to a Rtc Tick, one can use the following approximate calculation.

#define RTC_SECOND (1 * 1000 * 1000)
#define RTC_MIN    (60ull * RTC_SECOND)
#define RTC_HOUR   (60ull * RTC_MIN)
#define RTC_DAY    (24ull * RTC_HOUR)
#define RTC_YEAR   (365ull * RTC_DAY)

rtc_tick = year * RTC_YEAR + day * RTC_DAY + hour * RTC_HOUR + min * RTC_MIN + second * RTC_SECOND + usec;

However, when you convert 1970/01/01 00:00:00.000000 to a Rtc Tick using this calculation, the result is 0xDCB731F0F1C000 (1969/09/11 00:00:00.000000), which is different from the result shown in some of the actual Rtc Tick examples.

// 0x00DCBFFEFF2BC000 - 0xDCB731F0F1C000 = 9676800000000 (just 112 day)

Up to this point, we have been doing simple calculations, but to accurately convert from DateTime to Rtc Tick, we need to take leap years into account. There were 478 leap years between 1/01/01 00:00:00.000000 and 1970/01/01 00:00:00.000000, but that not match the difference.

Therefore, to convert from DateTime to the correct Rtc Tick, the following complex calculation must be performed. Note that there is no proof yet that this calculation can convert to the correct Rtc Tick.

#define RTC_SECOND (1 * 1000 * 1000)
#define RTC_MIN    (60ull * RTC_SECOND)
#define RTC_HOUR   (60ull * RTC_MIN)
#define RTC_DAY    (24ull * RTC_HOUR)
#define RTC_YEAR   (365ull * RTC_DAY)

int datetime2tick(SceRtcTick *pTick, SceUInt32 year, SceUInt32 month, SceUInt32 day, SceUInt32 hour, SceUInt32 min, SceUInt32 second, SceUInt32 usec){
	pTick->tick = 0ull;
	SceBool target_year_is_leap = SCE_FALSE;
	SceUInt32 leap_count = 0;
	if ((year % 400) == 0 || ((year % 4) == 0 && (year % 100) != 0))
		target_year_is_leap = SCE_TRUE;
	for (int i=0; i<(year - 1); i++) {
		if ((i % 400) == 0 || ((i % 4) == 0 && (i % 100) != 0))
			leap_count = leap_count + 1;
	}
	SceUInt64 year_diff = leap_count / 365;
	SceUInt64 day_diff  = leap_count % 365;
	day_diff -= target_year_is_leap;
	pTick->tick = (SceUInt64)(year - 1) * RTC_YEAR + year_diff * RTC_YEAR + day_diff * RTC_DAY;
	for (int i=0; i<(month-1); i++)
		pTick->tick += g_month_list[target_year_is_leap * 12 + i] * RTC_DAY;
	pTick->tick += (day - 1) * RTC_DAY;
	pTick->tick += hour   * RTC_HOUR;
	pTick->tick += min    * RTC_MIN;
	pTick->tick += second * RTC_SECOND;
	pTick->tick += usec;
	return 0;
}

SceRtc Time Reversal Security

If some Rtc ticks in memory are lower than the constant set in SceRtc, those ticks are set to 0.

The Rtc tick constants vary per System Software version as they are updated with some System Software updates containing a newer SceRtc kernel module.

System Software Version SceRtc Hardcoded Date
< 1.00 ?
1.00 - 1.67 ?1.692? 2011/08/01
1.80 - 1.81 2012/06/01
2.00 - 2.61 2012/09/01
2.50 - 3.00 2013/01/01
3.30 - 3.36 2014/01/01
3.500.000 - 3.740.011 2015/01/01

SceRtcForDriver

Some RTC functions apparently not present on PS Vita even on 3.200.010 but present on PSP:
sceRtcTickAddMonths
sceRtcTickAddYears

sceRtcCompareTickForDriver

Version NID
0.920-3.740.011 0x0EBB3F12

Returns 0 if tick_1 == tick_2, -1 if tick_1 < tick_2 and 1 else.

int sceRtcCompareTickForDriver(const SceRtcTick *tick_1, const SceRtcTick *tick_2);

sceRtcConvertLocalTimeToUtcForDriver

Version NID
3.60 0xAD2F3544

sceRtcConvertUtcToLocalTimeForDriver

Version NID
3.60 0xC6E03DD4

sceRtcFormatRFC2822ForDriver

Version NID
3.60 0xBA3415F8

sceRtcFormatRFC2822LocalTimeForDriver

Version NID
3.60 0x1F7FC209

sceRtcFormatRFC3339ForDriver

Version NID
3.60 0xD32AC698
int sceRtcFormatRFC3339ForDriver(char *pszDateTime, const SceRtcTick *utc, int iTimeZoneMinutes);

sceRtcFormatRFC3339LocalTimeForDriver

Version NID
3.60 0x35925318

sceRtcGetAccumulativeTimeForDriver

Version NID
3.60 0x0A86FB04

Also present in PSP under the official names sceRtcGetAccumulativeTime and sceRtcGetAccumlativeTime.

SceULong64 sceRtcGetAccumulativeTimeForDriver(void);

sceRtcGetAlarmTickForDriver

Version NID
3.60 0xC838275A

sceRtcGetCurrentAdNetworkTickForDriver

Version NID
3.60 0x3E3C09A0

sceRtcGetCurrentClockForDriver

Version NID
3.60 0xA930CD1A

sceRtcGetCurrentClockLocalTimeForDriver

Version NID
3.60 0x7DC0DF93

sceRtcGetCurrentDebugNetworkTickForDriver

Version NID
3.60 0xC141632A

sceRtcGetCurrentGpsTickForDriver

Version NID
3.60 0xF69B610F

sceRtcGetCurrentNetworkTickForDriver

Version NID
3.60 0xF1517B38

If the current NetworkTick is less than 2015/01/01, the system will ignore the registry setting and update the NetworkTick from the internet.

int sceRtcGetCurrentNetworkTickForDriver(SceRtcTick *tick);

sceRtcGetCurrentRetainedNetworkTickForDriver

Version NID
3.60 0x40B4BCFF

sceRtcGetCurrentTickForDriver

Version NID
3.60 0xDEC408D4

sceRtcGetCurrentSecureTickForDriver

Version NID
1.03-3.60 0x401C0954

If the current SecureTick is less than 2015/01/01, it sets 0xDDDEF8B3A14000(1980/01/01 00:00:00 UTC) to the Secure Tick and returns error code 0x80251002.

int sceRtcGetCurrentSecureTickForDriver(SceRtcTick *tick);

sceRtcTickAddTicksForDriver

Version NID
0.931.010-3.600.011 0xCE51C2A1

Adds time (in ticks) to a Rtc tick structure.

int sceRtcTickAddTicksForDriver(SceRtcTick *pDst, const SceRtcTick *pSrc, SceUInt64 num_ticks);

sceRtcTickAddMicrosecondsForDriver

Version NID
3.200.010 0xA82AC5B3

Adds time (in microseconds) to a time structure (in nanosecond).

int sceRtcTickAddMicrosecondsForDriver(SceRtcTick *pDst, const SceRtcTick *pSrc, SceUInt64 microseconds);

sceRtcTickAddSecondsForDriver

Version NID
0.931.010-3.600.011 0x9C8AF264

Adds time (in second) to a time structure (in nanosecond).

int sceRtcTickAddSecondsForDriver(SceRtcTick *pDst, const SceRtcTick *pSrc, SceUInt64 seconds);

sceRtcTickAddMinutesForDriver

Version NID
3.60 0x0F9E02EF
int sceRtcTickAddMinutesForDriver(SceRtcTick *pDst, const SceRtcTick *pSrc, SceUInt64 seconds);

sceRtcTickAddHoursForDriver

Version NID
3.200.010 0x32E50C36
int sceRtcTickAddHoursForDriver(SceRtcTick *pDst, const SceRtcTick *pSrc, SceUInt32 hours);

sceRtcTickAddDaysForDriver

Version NID
3.60 0x0CB72FAF

Used by SceCompat#sceCompatSetUpdateState.

int sceRtcTickAddDaysForDriver(SceRtcTick *pDst, const SceRtcTick *pSrc, SceUInt32 days);

sceRtcTickAddWeeksForDriver

Version NID
3.200.010 0x24209FBF
int sceRtcTickAddWeeksForDriver(SceRtcTick *pDst, const SceRtcTick *pSrc, SceUInt32 weeks);

sceRtcConvertDateTimeToTickForDriver

Version NID
0.990.000-3.740.011 0xF139E359

This is a guessed name. This may be the reciprocal function of #sceRtcConvertTickToDateTimeForDriver.

int sceRtcConvertDateTimeToTickForDriver(const SceDateTime *dateTime, SceRtcTick *pTick);

sceRtcConvertTickToDateTimeForDriver

Version NID
1.03-3.60 0x42A0DFCB

This is a guessed name. This may be the reciprocal function of #sceRtcConvertDateTimeToTickForDriver.

Used with the result of #sceRtcGetCurrentSecureTickForDriver. Used by SceCoredump, SceSblGcAuthMgr.

int sceRtcConvertTickToDateTimeForDriver(SceDateTime *pDateTime, const SceRtcTick *tick);

sceRtcConvertDateTimeToUnixTimeForDriver

Version NID
3.60 0x497B5DC9

This is a guessed name. This may be the reciprocal function of #sceRtcConvertUnixTimeToDateTimeForDriver.

Used by SceCoredump.

int sceRtcConvertDateTimeToUnixTimeForDriver(const SceDateTime *dateTime, SceUInt64 *pMicroseconds);

sceRtcConvertUnixTimeToDateTimeForDriver

Version NID
3.60 0xDE9F4515

This is a guessed name. This may be the reciprocal function of #sceRtcConvertDateTimeToUnixTimeForDriver.

This function does: microseconds * 1000000 + 0xdcbffeff2bc000. 0xdcbffeff2bc000 represents UNIX time i.e. the date 1970/01/01 00:00:00.000000. The microseconds is multiplied by 1000000 to convert from microseconds to seconds.

int sceRtcConvertUnixTimeToDateTimeForDriver(SceDateTime *pDateTime, const SceUInt32 microseconds);

sceRtcConvertDateTimeToFatTimeForDriver

Version NID
3.200.010 0x09AF419B

This is a guessed name. Official name may be sceRtcFormatRFC3339LocalTimeForDriver (see PSP sceRtc).

int sceRtcConvertDateTimeToFatTimeForDriver(const SceDateTime *pDateTime, SceUInt32 *pFatTime);

sceRtcSetCurrentAuxTickForDriver

Version NID
0.990.000-3.740.011 0xA7236656
int sceRtcSetCurrentAuxTickForDriver(SceRtcTick *tick);

sceRtcGetLastAdjustedTickForDriver

Version NID
3.60 0x8A987573

sceRtcGetLastReincarnatedTickForDriver

Version NID
3.60 0x3D614A9A

sceRtcGetSecureAlarmTickForDriver

Version NID
3.60 0xBD53731C

sceRtcSynchronizeForDriver

Version NID
3.60-3.74 0xA2D280B4

Initializes SceRtc internal flags.

int sceRtcSynchronizeForDriver(void);

SceRtcForDriver_ABA035B7

Version NID
3.60 0xABA035B7

Reset all SceRtc internal flags to 0.

Returns 0.

int SceRtcForDriver_ABA035B7(void);

sceRtcGetCurrentToolSecureTickForDriver

Version NID
0.990-3.60 0xA0D7899A

This is a guessed name.

Used on Tool only. Used when checking DevKit activation license expire date.

Creates a tick using SceKernelThreadMgr#sceKernelGetSystemTimeWideForDriver.

int sceRtcGetCurrentToolSecureTickForDriver(SceRtcTick *pTick);

sceRtcIsAlarmedForDriver

Version NID
3.60 0xCD295F0C

sceRtcIsSecureAlarmedForDriver

Version NID
3.60 0xE39F2ABE

sceRtcRegisterCallbackForDriver

Version NID
3.60 0x5220870D

sceRtcRegisterSecureAlarmCallbackForDriver

Version NID
3.60 0xCF84DFC0

sceRtcSetAlarmTickForDriver

Version NID
3.60 0xD610C646

sceRtcSetConfForDriver

Version NID
3.60 0xACFE5A9F

sceRtcSetCurrentDebugNetworkTickForDriver

Version NID
3.60 0xAAB6053F

sceRtcSetCurrentNetworkTickForDriver

Version NID
3.60 0x162E486E

sceRtcSetCurrentSecureTickForDriver

Version NID
3.60 0x7D431C87

sceRtcSetCurrentTickForDriver

Version NID
3.60 0x70A78CD2

sceRtcSetSecureAlarmTickForDriver

Version NID
3.60 0x8333790D

sceRtcUnregisterCallbackForDriver

Version NID
3.60 0x9546C68B

sceRtcUnregisterSecureAlarmCallbackForDriver

Version NID
3.60 0xEDDC2325

SceRtcForDriver_FFD7A04F

Version NID
3.60 0xFFD7A04F

Used indirectly by SceProcessmgr#sceKernelLibcTime.

SceRtcForDriver_9097EF0D

Version NID
3.60 0x9097EF0D

Used indirectly by SceProcessmgr.

sceRtcGetDayOfWeekForDriver

Version NID
3.60 0x0F800878

Used indirectly by SceProcessmgr.

int sceRtcGetDayOfWeekForDriver(SceUInt32 year, SceUInt32 month, SceUInt32 day)

sceRtcCheckValidForDriver

Version NID
3.200.010 0xADF63D7C
int sceRtcCheckValidForDriver(const SceDateTime *pDateTime);

sceRtcGetOneSecondForDriver

Version NID
3.200.010 0x6965E5DF

This is a guessed name.

SceUInt32 sceRtcGetOneSecondForDriver(void);

sceRtcIsLeapYearForDriver

Version NID
3.200.010 0x6F96FAA5
SceBool sceRtcIsLeapYearForDriver(SceUInt32 year);

SceRtcForDriver_A1F41AE2

Version NID
3.200.010 0xA1F41AE2

Official name may be either sceRtcGetWin32FileTime (see PSP sceRtc).

int SceRtcForDriver_A1F41AE2(SceRtcTick *pTick, const char *str);

SceRtcForDriver_BA14600F

Version NID
3.200.010 0xBA14600F

Official name may be sceRtcSetWin32FileTime (see PSP sceRtc).

It may be related to FILETIME on Windows.

int SceRtcForDriver_BA14600F(SceRtcTick *pDst, SceUInt64 a2);

sceRtcGetDaysInMonthForDriver

Version NID
3.200.010 0xC2DC38D9

Retrieves the number of days in the month of a specific year.

For example, in February 1970 there were 28 days versus 29 days in February 1972.

int sceRtcGetDaysInMonthForDriver(SceUInt32 year, SceUInt32 month);

SceRtc

_sceRtcGetCurrentNetworkTick

Version NID
1.69-3.60 0x06F734FE

_sceRtcConvertLocalTimeToUtc

Version NID
1.69-3.60 0x0FC8AC41

_sceRtcConvertUtcToLocalTime

Version NID
1.69-3.60 0x1E61DDA4

_sceRtcGetCurrentTick

Version NID
1.69-3.60 0x247EE33B

_sceRtcGetCurrentClock

Version NID
1.69-3.60 0x24947354

sceRtcGetAccumulativeTime

Version NID
1.69-3.60 0x258BE8EC

Also present in PSP under the official names sceRtcGetAccumulativeTime and sceRtcGetAccumlativeTime.

SceULong64 sceRtcGetAccumulativeTime(void);

_sceRtcFormatRFC2822

Version NID
1.69-3.60 0x2CD6AC86

_sceRtcGetCurrentGpsTick

Version NID
1.69-3.60 0x3BA820E5

_sceRtcGetCurrentClockLocalTime

Version NID
1.69-3.60 0x41A6C861

_sceRtcFormatRFC3339LocalTime

Version NID
1.69-3.60 0x4836474D

_sceRtcFormatRFC2822LocalTime

Version NID
1.69-3.60 0x4C7ED349

_sceRtcFormatRFC3339

Version NID
1.69-3.60 0x7EE2CBEF

_sceRtcGetCurrentRetainedNetworkTick

Version NID
1.69-3.60 0xC17EA809

_sceRtcGetLastReincarnatedTick

Version NID
1.69-3.60 0xE13D0FE5

_sceRtcGetLastAdjustedTick

Version NID
1.69-3.60 0xEA157EC5

_sceRtcGetCurrentAdNetworkTick

Version NID
3.60 0x76EFA8FE

_sceRtcGetCurrentDebugNetworkTick

Version NID
3.60 0xBF639B21

How to get current time and date

See also Rtc Tick.

Getting the current time and date involves Syscon scratchpad and Syscon command 0x11. Syscon command 0x11 returns twice the number of seconds Syscon has been running since its power on. Syscon scratchpad contains at offset 0x10 the timestamp when Syscon "started" running. It is stored in the following format: microseconds since 01/01/0001 and divided by 2^19. By adding those values together, the OS obtains the current time and date.

In pseudocode:

last_reincarnated_tick = syscon_read_scratchpad(offset=0x10, size=5)
up_time_half_seconds = syscon_cmd_read(cmd=0x11, size=4)
UTC = timedelta(microseconds=last_reincarnated_tick * (1<<19)) + datetime(1, 1, 1) + timedelta(seconds=up_time_half_seconds*2)

See also