Skip to content

Commit

Permalink
[WiiU] Add missing time/clock libc functions
Browse files Browse the repository at this point in the history
Add some timing functions so that we can know the time (woo-hoo?)
I use errno here, which worries me a bit. I wouldn't put it past
devkitPPC to have it as a null pointer or something.

Can confirm this makes XMB's clock work, much to @cucholix's delight;
I'm sure ;D
  • Loading branch information
ashquarky committed Jan 30, 2018
1 parent 3d2c579 commit 3a442af
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
5 changes: 0 additions & 5 deletions frontend/drivers/platform_wiiu.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,11 +507,6 @@ int main(int argc, char **argv)
return 0;
}

unsigned long _times_r(struct _reent *r, struct tms *tmsbuf)
{
return 0;
}

void __eabi(void)
{

Expand Down
1 change: 1 addition & 0 deletions wiiu/system/imports.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ IMPORT(OSGetCoreId);
IMPORT(OSIsMainCore);
IMPORT(OSGetSystemTime);
IMPORT(OSGetSystemTick);
IMPORT(OSGetTime);
IMPORT(OSGetSymbolName);
IMPORT(OSGetSharedData);
IMPORT(OSEffectiveToPhysical);
Expand Down
64 changes: 59 additions & 5 deletions wiiu/system/missing_libc_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include <wiiu/os.h>
#include <pwd.h>
#include <features/features_cpu.h>
#include <sys/reent.h>
#include <errno.h>
#include <time.h>

/* This is usually in libogc; we can't use that on wiiu */
int usleep(useconds_t microseconds) {
Expand Down Expand Up @@ -51,11 +54,62 @@ struct passwd* getpwuid(uid_t uid) {
return &out;
}

/* Try to vaugely spoof the POISX clock. Epoch is off by about 30 */
/* years, so this could be better... */
/* Only has second accuracy since I'm lazy. */
/* Basic Cafe OS clock thingy. */
int _gettimeofday_r(struct _reent *ptr,
struct timeval* ptimeval,
void* ptimezone) {

OSTime cosTime;
uint64_t cosSecs;
uint32_t cosUSecs;
time_t unixSecs;

/* We need somewhere to put our output */
if (ptimeval == NULL) {
errno = EFAULT;
return -1;
}

/* Get Cafe OS clock in seconds; epoch 2000-01-01 00:00 */
cosTime = OSGetTime();
cosSecs = ticks_to_sec(cosTime);

/* Get extra milliseconds */
cosUSecs = ticks_to_us(cosTime) - (cosSecs * 1000000);

/* Convert to Unix time, epoch 1970-01-01 00:00.
Constant value is seconds between 1970 and 2000.
time_t is 32bit here, so the Wii U is vulnerable to the 2038 problem. */
unixSecs = cosSecs + 946684800;

ptimeval->tv_sec = unixSecs;
ptimeval->tv_usec = cosUSecs;
return 0;
}

/* POSIX clock in all its glory */
int clock_gettime(clockid_t clk_id, struct timespec* tp) {
int64_t time_usec = cpu_features_get_time_usec();
tp->tv_sec = time_usec / 1000000;
struct timeval ptimeval = { 0 };
int ret = 0;
OSTime cosTime;

if (tp == NULL) {
errno = EFAULT;
return -1;
}

switch (clk_id) {
case CLOCK_REALTIME:
/* Just wrap gettimeofday. Cheating, I know. */
ret = _gettimeofday_r(NULL, &ptimeval, NULL);
if (ret) return -1;

tp->tv_sec = ptimeval.tv_sec;
tp->tv_nsec = ptimeval.tv_usec * 1000;
break;
default:
errno = EINVAL;
return -1;
}
return 0;
}

0 comments on commit 3a442af

Please sign in to comment.