blob: 9f5ec4bbb7e3c8ff662b118f28595a89688dec5a [file] [log] [blame]
/*
* Test the RTAS interface
*/
#include <libcflat.h>
#include <util.h>
#include <asm/rtas.h>
#define DAYS(y,m,d) (365UL * (y) + ((y) / 4) - ((y) / 100) + ((y) / 400) + \
367UL * (m) / 12 + \
(d))
static unsigned long mktime(int year, int month, int day,
int hour, int minute, int second)
{
unsigned long epoch;
/* Put February at end of the year to avoid leap day this year */
month -= 2;
if (month <= 0) {
month += 12;
year -= 1;
}
/* compute epoch: substract DAYS(since_March(1-1-1970)) */
epoch = DAYS(year, month, day) - DAYS(1969, 11, 1);
epoch = epoch * 24 + hour;
epoch = epoch * 60 + minute;
epoch = epoch * 60 + second;
return epoch;
}
#define DELAY 1
#define MAX_LOOP 10000000
static void check_get_time_of_day(unsigned long start)
{
uint32_t token;
int ret;
int now[8];
unsigned long t1, t2, count;
ret = rtas_token("get-time-of-day", &token);
report(ret == 0, "token available");
if (ret)
return;
ret = rtas_call(token, 0, 8, now);
report(ret == 0, "execution");
report(now[5] >= 0 && now[5] <= 59, "second");
report(now[4] >= 0 && now[4] <= 59, "minute");
report(now[3] >= 0 && now[3] <= 23, "hour");
report(now[2] >= 1 && now[2] <= 31, "day");
report(now[1] >= 1 && now[1] <= 12, "month");
report(now[0] >= 1970, "year");
report(mktime(now[0], now[1], now[2], now[3], now[4], now[5]) - start < 3,
"accuracy (< 3s)");
ret = rtas_call(token, 0, 8, now);
t1 = mktime(now[0], now[1], now[2], now[3], now[4], now[5]);
count = 0;
do {
ret = rtas_call(token, 0, 8, now);
t2 = mktime(now[0], now[1], now[2], now[3], now[4], now[5]);
count++;
} while (t1 + DELAY > t2 && count < MAX_LOOP);
report(t1 + DELAY <= t2, "running");
}
static void check_set_time_of_day(void)
{
uint32_t stod_token, gtod_token;
int ret;
int date[8];
unsigned long t1, t2, count;
ret = rtas_token("set-time-of-day", &stod_token);
report(ret == 0, "token available");
if (ret)
return;
/* 23:59:59 28/2/2000 */
ret = rtas_call(stod_token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
report(ret == 0, "execution");
/* check it has worked */
ret = rtas_token("get-time-of-day", &gtod_token);
assert(ret == 0);
ret = rtas_call(gtod_token, 0, 8, date);
report(ret == 0, "re-read");
t1 = mktime(2000, 2, 28, 23, 59, 59);
t2 = mktime(date[0], date[1], date[2],
date[3], date[4], date[5]);
report(t2 - t1 < 2, "result");
/* check it is running */
count = 0;
do {
ret = rtas_call(gtod_token, 0, 8, date);
t2 = mktime(date[0], date[1], date[2],
date[3], date[4], date[5]);
count++;
} while (t1 + DELAY > t2 && count < MAX_LOOP);
report(t1 + DELAY <= t2, "running");
}
int main(int argc, char **argv)
{
int len;
long val;
report_prefix_push("rtas");
if (argc < 2)
report_abort("no test specified");
report_prefix_push(argv[1]);
if (strcmp(argv[1], "get-time-of-day") == 0) {
len = parse_keyval(argv[2], &val);
if (len == -1) {
printf("Missing parameter \"date\"\n");
abort();
}
argv[2][len] = '\0';
check_get_time_of_day(val);
} else if (strcmp(argv[1], "set-time-of-day") == 0) {
check_set_time_of_day();
} else {
printf("Unknown subtest\n");
abort();
}
report_prefix_pop();
report_prefix_pop();
return report_summary();
}