/*
 * 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();
}
