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