1 /*
2 * Test the RTAS interface
3 */
4
5 #include <libcflat.h>
6 #include <util.h>
7 #include <asm/rtas.h>
8
9 #define DAYS(y,m,d) (365UL * (y) + ((y) / 4) - ((y) / 100) + ((y) / 400) + \
10 367UL * (m) / 12 + \
11 (d))
12
mktime(int year,int month,int day,int hour,int minute,int second)13 static unsigned long mktime(int year, int month, int day,
14 int hour, int minute, int second)
15 {
16 unsigned long epoch;
17
18 /* Put February at end of the year to avoid leap day this year */
19
20 month -= 2;
21 if (month <= 0) {
22 month += 12;
23 year -= 1;
24 }
25
26 /* compute epoch: substract DAYS(since_March(1-1-1970)) */
27
28 epoch = DAYS(year, month, day) - DAYS(1969, 11, 1);
29
30 epoch = epoch * 24 + hour;
31 epoch = epoch * 60 + minute;
32 epoch = epoch * 60 + second;
33
34 return epoch;
35 }
36
37 #define DELAY 1
38 #define MAX_LOOP 10000000
39
check_get_time_of_day(unsigned long start)40 static void check_get_time_of_day(unsigned long start)
41 {
42 uint32_t token;
43 int ret;
44 int now[8];
45 unsigned long t1, t2, count;
46
47 ret = rtas_token("get-time-of-day", &token);
48 report(ret == 0, "token available");
49 if (ret)
50 return;
51
52 ret = rtas_call(token, 0, 8, now);
53 report(ret == 0, "execution");
54
55 report(now[5] >= 0 && now[5] <= 59, "second");
56 report(now[4] >= 0 && now[4] <= 59, "minute");
57 report(now[3] >= 0 && now[3] <= 23, "hour");
58 report(now[2] >= 1 && now[2] <= 31, "day");
59 report(now[1] >= 1 && now[1] <= 12, "month");
60 report(now[0] >= 1970, "year");
61 report(mktime(now[0], now[1], now[2], now[3], now[4], now[5]) - start < 3,
62 "accuracy (< 3s)");
63
64 ret = rtas_call(token, 0, 8, now);
65 t1 = mktime(now[0], now[1], now[2], now[3], now[4], now[5]);
66 count = 0;
67 do {
68 ret = rtas_call(token, 0, 8, now);
69 t2 = mktime(now[0], now[1], now[2], now[3], now[4], now[5]);
70 count++;
71 } while (t1 + DELAY > t2 && count < MAX_LOOP);
72 report(t1 + DELAY <= t2, "running");
73 }
74
check_set_time_of_day(void)75 static void check_set_time_of_day(void)
76 {
77 uint32_t stod_token, gtod_token;
78 int ret;
79 int date[8];
80 unsigned long t1, t2, count;
81
82 ret = rtas_token("set-time-of-day", &stod_token);
83 report(ret == 0, "token available");
84 if (ret)
85 return;
86
87 /* 23:59:59 28/2/2000 */
88
89 ret = rtas_call(stod_token, 7, 1, NULL, 2000, 2, 28, 23, 59, 59);
90 report(ret == 0, "execution");
91
92 /* check it has worked */
93 ret = rtas_token("get-time-of-day", >od_token);
94 assert(ret == 0);
95 ret = rtas_call(gtod_token, 0, 8, date);
96 report(ret == 0, "re-read");
97 t1 = mktime(2000, 2, 28, 23, 59, 59);
98 t2 = mktime(date[0], date[1], date[2],
99 date[3], date[4], date[5]);
100 report(t2 - t1 < 2, "result");
101
102 /* check it is running */
103 count = 0;
104 do {
105 ret = rtas_call(gtod_token, 0, 8, date);
106 t2 = mktime(date[0], date[1], date[2],
107 date[3], date[4], date[5]);
108 count++;
109 } while (t1 + DELAY > t2 && count < MAX_LOOP);
110 report(t1 + DELAY <= t2, "running");
111 }
112
main(int argc,char ** argv)113 int main(int argc, char **argv)
114 {
115 int len;
116 long val;
117
118 report_prefix_push("rtas");
119
120 if (argc < 2)
121 report_abort("no test specified");
122
123 report_prefix_push(argv[1]);
124
125 if (strcmp(argv[1], "get-time-of-day") == 0) {
126
127 len = parse_keyval(argv[2], &val);
128 if (len == -1) {
129 printf("Missing parameter \"date\"\n");
130 abort();
131 }
132 argv[2][len] = '\0';
133
134 check_get_time_of_day(val);
135
136 } else if (strcmp(argv[1], "set-time-of-day") == 0) {
137
138 check_set_time_of_day();
139
140 } else {
141 printf("Unknown subtest\n");
142 abort();
143 }
144
145 report_prefix_pop();
146
147 report_prefix_pop();
148
149 return report_summary();
150 }
151