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