diff --git a/gc/ogc/card.h b/gc/ogc/card.h index 202d7f5a1..d098329be 100644 --- a/gc/ogc/card.h +++ b/gc/ogc/card.h @@ -212,7 +212,7 @@ typedef struct _card_direntry { typedef struct _card_stat { u8 filename[CARD_FILENAMELEN]; u32 len; - u32 time; //time since 1970 in seconds + u32 time; //time since 2000 in seconds u8 gamecode[4]; u8 company[2]; u8 banner_fmt; diff --git a/libogc/card.c b/libogc/card.c index 5e1be457e..7f418c385 100644 --- a/libogc/card.c +++ b/libogc/card.c @@ -36,6 +36,7 @@ distribution. #include #include "asm.h" #include "processor.h" +#include "lwp_watchdog.h" #include "system.h" #include "ogcsys.h" #include "cache.h" @@ -229,8 +230,6 @@ static sys_resetinfo card_resetinfo = { 127 }; -extern unsigned long gettick(void); -extern long long gettime(void); extern syssram* __SYS_LockSram(void); extern syssramex* __SYS_LockSramEx(void); extern u32 __SYS_UnlockSram(u32 write); @@ -1182,7 +1181,7 @@ static void __write_callback(s32 chn,s32 result) if(file->len<=0) { dirblock = __card_getdirblock(card); entry = &dirblock->entries[file->filenum]; - entry->last_modified = time(NULL); + entry->last_modified = ticks_to_secs(gettime()); cb = card->card_api_cb; card->card_api_cb = NULL; if((ret=__card_updatedir(chn,cb))>=0) return; @@ -1826,7 +1825,7 @@ static void __card_createfatcallback(s32 chn,s32 result) entry->icon_speed = 0; entry->pad_01 = 0xffff; entry->icon_speed = (entry->icon_speed&~CARD_SPEED_MASK)|CARD_SPEED_FAST; - entry->last_modified = time(NULL); + entry->last_modified = ticks_to_secs(gettime()); file->offset = 0; file->iblock = card->curr_fileblock; @@ -3174,7 +3173,7 @@ s32 CARD_SetStatusAsync(s32 chn,s32 fileno,card_stat *stats,cardcallback callbac if(entry->icon_addr==-1) entry->icon_fmt = ((entry->icon_fmt&~CARD_ICON_MASK)|CARD_ICON_CI); - entry->last_modified = time(NULL); + entry->last_modified = ticks_to_secs(gettime()); if((ret=__card_updatedir(chn,callback))>=0) return ret; } diff --git a/libogc/dvd.c b/libogc/dvd.c index 47c2b1c8e..c806c7c86 100644 --- a/libogc/dvd.c +++ b/libogc/dvd.c @@ -394,7 +394,6 @@ static s32 DVD_LowSetOffset(s64 offset,dvdcallbacklow cb); extern void udelay(int us); extern u32 diff_msec(unsigned long long start,unsigned long long end); -extern long long gettime(void); extern void __MaskIrq(u32); extern void __UnmaskIrq(u32); extern syssramex* __SYS_LockSramEx(void); @@ -1345,7 +1344,7 @@ static void __DVDInterruptHandler(u32 nIrq,void *pCtx) _diReg[0] = (ir|irm); - now = gettime(); + now = SYS_Time(); diff = diff_msec(__dvd_lastresetend,now); if(__dvd_resetoccured && diff>200) { status = _diReg[1]; @@ -2112,7 +2111,7 @@ static void DVD_LowReset(u32 reset_mode) _piReg[9] = val; __dvd_resetoccured = 1; - __dvd_lastresetend = gettime(); + __dvd_lastresetend = SYS_Time(); __dvd_drivestate |= DVD_DRIVERESET; } diff --git a/libogc/exi.c b/libogc/exi.c index 8bf454b1a..ebff701e7 100644 --- a/libogc/exi.c +++ b/libogc/exi.c @@ -35,6 +35,7 @@ distribution. #include "irq.h" #include "processor.h" #include "spinlock.h" +#include "system.h" #include "exi.h" #include "gcutil.h" #include "lwp_queue.h" @@ -179,7 +180,7 @@ static s32 __exi_probe(s32 nChn) last_exi_idtime[nChn] = 0; } if(_exiReg[nChn*5]&EXI_EXT_BIT) { - time = gettime(); + time = SYS_Time(); if(last_exi_idtime[nChn]==0) last_exi_idtime[nChn] = time; if((val=diff_usec(last_exi_idtime[nChn],time)+10)<30) ret = 0; else ret = 1; diff --git a/libogc/lwp_watchdog.c b/libogc/lwp_watchdog.c index 264d864d3..05223eeb7 100644 --- a/libogc/lwp_watchdog.c +++ b/libogc/lwp_watchdog.c @@ -1,6 +1,7 @@ #include #include #include "asm.h" +#include "system.h" #include "lwp_threads.h" #include "lwp_watchdog.h" @@ -28,7 +29,7 @@ static void __lwp_wd_settimer(wd_cntrl *wd) u32 ul[2]; } v; - now = gettime(); + now = SYS_Time(); v.ull = diff = diff_ticks(now,wd->fire); #ifdef _LWPWD_DEBUG printf("__lwp_wd_settimer(%p,%llu,%lld)\n",wd,wd->fire,diff); @@ -139,7 +140,7 @@ void __lwp_wd_tickle(lwp_queue *queue) if(__lwp_queue_isempty(queue)) return; wd = __lwp_wd_first(queue); - now = gettime(); + now = SYS_Time(); diff = diff_ticks(now,wd->fire); #ifdef _LWPWD_DEBUG printf("__lwp_wd_tickle(%p,%08x%08x,%08x%08x,%08x%08x,%08x%08x)\n",wd,(u32)(now>>32),(u32)now,(u32)(wd->start>>32),(u32)wd->start,(u32)(wd->fire>>32),(u32)wd->fire,(u32)(diff>>32),(u32)diff); @@ -170,7 +171,7 @@ void __lwp_wd_adjust(lwp_queue *queue,u32 dir,s64 interval) u64 abs_int; _CPU_ISR_Disable(level); - abs_int = gettime()+LWP_WD_ABS(interval); + abs_int = SYS_Time()+LWP_WD_ABS(interval); if(!__lwp_queue_isempty(queue)) { switch(dir) { case LWP_WD_BACKWARD: @@ -183,7 +184,7 @@ void __lwp_wd_adjust(lwp_queue *queue,u32 dir,s64 interval) break; } else { abs_int -= __lwp_wd_first(queue)->fire; - __lwp_wd_first(queue)->fire = gettime(); + __lwp_wd_first(queue)->fire = SYS_Time(); __lwp_wd_tickle(queue); if(__lwp_queue_isempty(queue)) break; } diff --git a/libogc/lwp_watchdog.inl b/libogc/lwp_watchdog.inl index 758dc64c9..42e8846a0 100644 --- a/libogc/lwp_watchdog.inl +++ b/libogc/lwp_watchdog.inl @@ -1,6 +1,7 @@ #ifndef __LWP_WATCHDOG_INL__ #define __LWP_WATCHDOG_INL__ +#include "system.h" #include "lwp_watchdog.h" static __inline__ void __lwp_wd_initialize(wd_cntrl *wd,wd_service_routine routine,u32 id,void *usr_data) @@ -63,7 +64,7 @@ static __inline__ void __lwp_wd_tickle_ticks(void) static __inline__ void __lwp_wd_insert_ticks(wd_cntrl *wd,s64 interval) { - wd->start = gettime(); + wd->start = SYS_Time(); wd->fire = (wd->start+LWP_WD_ABS(interval)); __lwp_wd_insert(&_wd_ticks_queue,wd); } diff --git a/libogc/si.c b/libogc/si.c index a13e4df42..48c557d70 100644 --- a/libogc/si.c +++ b/libogc/si.c @@ -117,7 +117,6 @@ static syswd_t si_alarm[4]; #endif static vu16* const _viReg = (u16*)0xCC002000; - static u32 __si_transfer(s32 chan,void *out,u32 out_len,void *in,u32 in_len,SICallback cb); static __inline__ struct _xy* __si_getxy(void) @@ -171,7 +170,7 @@ static u32 __si_completetransfer(void) if(sicntrl.chan==-1) return sisr; - xferTime[sicntrl.chan] = gettime(); + xferTime[sicntrl.chan] = SYS_Time(); in = (u32*)sicntrl.in; cnt = (sicntrl.in_bytes/4); @@ -188,7 +187,7 @@ static u32 __si_completetransfer(void) if(sisr&SISR_NORESPONSE && !(si_type[sicntrl.chan]&SI_ERROR_BUSY)) si_type[sicntrl.chan] = SI_ERROR_NO_RESPONSE; if(!sisr) sisr = SISR_COLLISION; } else { - typeTime[sicntrl.chan] = gettime(); + typeTime[sicntrl.chan] = SYS_Time(); sisr = 0; } @@ -268,7 +267,7 @@ static void __si_gettypecallback(s32 chan,u32 type) u32 sipad_en,id; si_type[chan] = (si_type[chan]&~SI_ERROR_BUSY)|type; - typeTime[chan] = gettime(); + typeTime[chan] = SYS_Time(); #ifdef _SI_DEBUG printf("__si_gettypecallback(%d,%08x,%08x)\n",chan,type,si_type[chan]); #endif @@ -336,7 +335,7 @@ static void __si_transfernext(u32 chan) printf("__si_transfernext(chan = %d,sipacket.chan = %d)\n",chan,sipacket[chan].chan); #endif if(sipacket[chan].chan!=-1) { - now = gettime(); + now = SYS_Time(); diff = (now - sipacket[chan].fire); if(diff>=0) { if(!__si_transfer(sipacket[chan].chan,sipacket[chan].out,sipacket[chan].out_bytes,sipacket[chan].in,sipacket[chan].in_bytes,sipacket[chan].callback)) break; @@ -570,7 +569,7 @@ u32 SI_Transfer(s32 chan,void *out,u32 out_len,void *in,u32 in_len,SICallback cb _CPU_ISR_Disable(level); if(sipacket[chan].chan==-1 && sicntrl.chan!=chan) { ret = 1; - fire = now = gettime(); + fire = now = SYS_Time(); if(us_delay) fire = xferTime[chan]+microsecs_to_ticks(us_delay); diff = (now - fire); if(diff<0) { @@ -605,12 +604,12 @@ u32 SI_GetType(s32 chan) printf("SI_GetType(%d)\n",chan); #endif _CPU_ISR_Disable(level); - now = gettime(); + now = SYS_Time(); type = si_type[chan]; diff = (now - typeTime[chan]); if(sicntrl.poll&(0x80>>chan)) { if(type!=SI_ERROR_NO_RESPONSE) { - typeTime[chan] = gettime(); + typeTime[chan] = SYS_Time(); _CPU_ISR_Restore(level); return type; } @@ -621,7 +620,7 @@ u32 SI_GetType(s32 chan) } else if(diff<=millisecs_to_ticks(75)) si_type[chan] = SI_ERROR_BUSY; else si_type[chan] = type = SI_ERROR_BUSY; - typeTime[chan] = gettime(); + typeTime[chan] = SYS_Time(); SI_Transfer(chan,&cmdtypeandstatus$223,1,&si_type[chan],3,__si_gettypecallback,65); _CPU_ISR_Restore(level); diff --git a/libogc/system.c b/libogc/system.c index 589eea390..6fc08ed3c 100644 --- a/libogc/system.c +++ b/libogc/system.c @@ -33,6 +33,7 @@ distribution. #include #include #include +#include #include #include "asm.h" @@ -155,6 +156,7 @@ static powercallback __POWCallback = NULL; static u32 __sys_resetdown = 0; #endif +static vu64* const _bootTime = (u64*)0x800030d8; static vu16* const _viReg = (u16*)0xCC002000; static vu32* const _piReg = (u32*)0xCC003000; static vu16* const _memReg = (u16*)0xCC004000; @@ -215,6 +217,8 @@ extern void __libogc_exit(int status); extern void * __libogc_sbrk_r(struct _reent *ptr, ptrdiff_t incr); extern int __libogc_gettod_r(struct _reent *ptr, struct timeval *tp, struct timezone *tz); extern int __libogc_nanosleep(const struct timespec *tb, struct timespec *rem); +extern u64 gettime(void); +extern void settime(u64); extern u8 __gxregs[]; extern u8 __text_start[]; @@ -981,9 +985,39 @@ u32 __SYS_GetRTC(u32 *gctime) return 0; } +static void __SYS_SetTime(s64 time) +{ + u32 level; + s64 now; + + _CPU_ISR_Disable(level); + now = gettime(); + now -= time; + now += *_bootTime; + *_bootTime = now; + settime(time); + EXI_ProbeReset(); + _CPU_ISR_Restore(level); +} + void __SYS_SetBootTime(void) { - settime(SYS_Time()); + u32 gctime; +#if defined(HW_RVL) + u32 bias; +#endif + + if(__SYS_GetRTC(&gctime)!=1) + return; + +#if defined(HW_RVL) + if(CONF_GetCounterBias(&bias) >= 0) + gctime += bias; +#else + gctime += SYS_GetCounterBias(); +#endif + + __SYS_SetTime(secs_to_ticks(gctime)); } u32 __SYS_LoadFont(void *src,void *dest) @@ -1113,9 +1147,10 @@ void SYS_PreMain(void) __IOS_InitializeSubsystems(); STM_RegisterEventHandler(__STMEventHandler); CONF_Init(); - __SYS_SetBootTime(); WII_Initialize(); #endif + + __SYS_SetBootTime(); } u32 SYS_ResetButtonDown(void) @@ -1914,18 +1949,12 @@ u32 SYS_GetHollywoodRevision(void) u64 SYS_Time(void) { - u64 current_time = 0; - u32 gmtime =0; - __SYS_GetRTC(&gmtime); - current_time = gmtime; -#ifdef HW_RVL - u32 bias; - if (CONF_GetCounterBias(&bias) >= 0) - current_time += bias; -#else - syssram* sram = __SYS_LockSram(); - current_time += sram->counter_bias; - __SYS_UnlockSram(0); -#endif - return (TB_TIMER_CLOCK * 1000) * current_time; + u32 level; + s64 now; + + _CPU_ISR_Disable(level); + now = gettime(); + now += *_bootTime; + _CPU_ISR_Restore(level); + return now; }