1433d6423SLionel Sambuc /* This file takes care of those system calls that deal with time. 2433d6423SLionel Sambuc * 3433d6423SLionel Sambuc * The entry points into this file are 4433d6423SLionel Sambuc * do_getres: perform the CLOCK_GETRES system call 5433d6423SLionel Sambuc * do_gettime: perform the CLOCK_GETTIME system call 6433d6423SLionel Sambuc * do_settime: perform the CLOCK_SETTIME system call 7433d6423SLionel Sambuc * do_time: perform the GETTIMEOFDAY system call 8433d6423SLionel Sambuc * do_stime: perform the STIME system call 9433d6423SLionel Sambuc */ 10433d6423SLionel Sambuc 11433d6423SLionel Sambuc #include "pm.h" 12433d6423SLionel Sambuc #include <minix/callnr.h> 13433d6423SLionel Sambuc #include <minix/com.h> 14433d6423SLionel Sambuc #include <signal.h> 15433d6423SLionel Sambuc #include <sys/time.h> 16433d6423SLionel Sambuc #include "mproc.h" 17433d6423SLionel Sambuc 18433d6423SLionel Sambuc /*===========================================================================* 19433d6423SLionel Sambuc * do_gettime * 20433d6423SLionel Sambuc *===========================================================================*/ 21433d6423SLionel Sambuc int do_gettime() 22433d6423SLionel Sambuc { 23433d6423SLionel Sambuc clock_t ticks, realtime, clock; 24433d6423SLionel Sambuc time_t boottime; 25433d6423SLionel Sambuc int s; 26433d6423SLionel Sambuc 27433d6423SLionel Sambuc if ( (s=getuptime(&ticks, &realtime, &boottime)) != OK) 28433d6423SLionel Sambuc panic("do_time couldn't get uptime: %d", s); 29433d6423SLionel Sambuc 30433d6423SLionel Sambuc switch (m_in.m_lc_pm_time.clk_id) { 31433d6423SLionel Sambuc case CLOCK_REALTIME: 32433d6423SLionel Sambuc clock = realtime; 33433d6423SLionel Sambuc break; 34433d6423SLionel Sambuc case CLOCK_MONOTONIC: 35433d6423SLionel Sambuc clock = ticks; 36433d6423SLionel Sambuc break; 37433d6423SLionel Sambuc default: 38433d6423SLionel Sambuc return EINVAL; /* invalid/unsupported clock_id */ 39433d6423SLionel Sambuc } 40433d6423SLionel Sambuc 41433d6423SLionel Sambuc mp->mp_reply.m_pm_lc_time.sec = boottime + (clock / system_hz); 42433d6423SLionel Sambuc mp->mp_reply.m_pm_lc_time.nsec = 43433d6423SLionel Sambuc (uint32_t) ((clock % system_hz) * 1000000000ULL / system_hz); 44433d6423SLionel Sambuc 45433d6423SLionel Sambuc return(OK); 46433d6423SLionel Sambuc } 47433d6423SLionel Sambuc 48433d6423SLionel Sambuc /*===========================================================================* 49433d6423SLionel Sambuc * do_getres * 50433d6423SLionel Sambuc *===========================================================================*/ 51433d6423SLionel Sambuc int do_getres() 52433d6423SLionel Sambuc { 53433d6423SLionel Sambuc switch (m_in.m_lc_pm_time.clk_id) { 54433d6423SLionel Sambuc case CLOCK_REALTIME: 55433d6423SLionel Sambuc case CLOCK_MONOTONIC: 56433d6423SLionel Sambuc /* tv_sec is always 0 since system_hz is an int */ 57433d6423SLionel Sambuc mp->mp_reply.m_pm_lc_time.sec = 0; 58433d6423SLionel Sambuc mp->mp_reply.m_pm_lc_time.nsec = 1000000000 / system_hz; 59433d6423SLionel Sambuc return(OK); 60433d6423SLionel Sambuc default: 61433d6423SLionel Sambuc return EINVAL; /* invalid/unsupported clock_id */ 62433d6423SLionel Sambuc } 63433d6423SLionel Sambuc } 64433d6423SLionel Sambuc 65433d6423SLionel Sambuc /*===========================================================================* 66433d6423SLionel Sambuc * do_settime * 67433d6423SLionel Sambuc *===========================================================================*/ 68433d6423SLionel Sambuc int do_settime() 69433d6423SLionel Sambuc { 70433d6423SLionel Sambuc int s; 71433d6423SLionel Sambuc 72433d6423SLionel Sambuc if (mp->mp_effuid != SUPER_USER) { 73433d6423SLionel Sambuc return(EPERM); 74433d6423SLionel Sambuc } 75433d6423SLionel Sambuc 76433d6423SLionel Sambuc switch (m_in.m_lc_pm_time.clk_id) { 77433d6423SLionel Sambuc case CLOCK_REALTIME: 78433d6423SLionel Sambuc s = sys_settime(m_in.m_lc_pm_time.now, m_in.m_lc_pm_time.clk_id, 79433d6423SLionel Sambuc m_in.m_lc_pm_time.sec, m_in.m_lc_pm_time.nsec); 80433d6423SLionel Sambuc return(s); 81433d6423SLionel Sambuc case CLOCK_MONOTONIC: /* monotonic cannot be changed */ 82433d6423SLionel Sambuc default: 83433d6423SLionel Sambuc return EINVAL; /* invalid/unsupported clock_id */ 84433d6423SLionel Sambuc } 85433d6423SLionel Sambuc } 86433d6423SLionel Sambuc 87433d6423SLionel Sambuc /*===========================================================================* 88433d6423SLionel Sambuc * do_time * 89433d6423SLionel Sambuc *===========================================================================*/ 90433d6423SLionel Sambuc int do_time() 91433d6423SLionel Sambuc { 92*ad80a203SDavid van Moolenbroek /* Perform the time(tp) system call. */ 93*ad80a203SDavid van Moolenbroek struct timespec tv; 94433d6423SLionel Sambuc 95*ad80a203SDavid van Moolenbroek (void)clock_time(&tv); 96433d6423SLionel Sambuc 97*ad80a203SDavid van Moolenbroek mp->mp_reply.m_pm_lc_time.sec = tv.tv_sec; 98*ad80a203SDavid van Moolenbroek mp->mp_reply.m_pm_lc_time.nsec = tv.tv_nsec; 99433d6423SLionel Sambuc return(OK); 100433d6423SLionel Sambuc } 101433d6423SLionel Sambuc 102433d6423SLionel Sambuc /*===========================================================================* 103433d6423SLionel Sambuc * do_stime * 104433d6423SLionel Sambuc *===========================================================================*/ 105433d6423SLionel Sambuc int do_stime() 106433d6423SLionel Sambuc { 107433d6423SLionel Sambuc /* Perform the stime(tp) system call. Retrieve the system's uptime (ticks 108433d6423SLionel Sambuc * since boot) and pass the new time in seconds at system boot to the kernel. 109433d6423SLionel Sambuc */ 110433d6423SLionel Sambuc clock_t uptime, realtime; 111433d6423SLionel Sambuc time_t boottime; 112433d6423SLionel Sambuc int s; 113433d6423SLionel Sambuc 114433d6423SLionel Sambuc if (mp->mp_effuid != SUPER_USER) { 115433d6423SLionel Sambuc return(EPERM); 116433d6423SLionel Sambuc } 117433d6423SLionel Sambuc if ( (s=getuptime(&uptime, &realtime, &boottime)) != OK) 118433d6423SLionel Sambuc panic("do_stime couldn't get uptime: %d", s); 119433d6423SLionel Sambuc boottime = m_in.m_lc_pm_time.sec - (realtime/system_hz); 120433d6423SLionel Sambuc 121433d6423SLionel Sambuc s= sys_stime(boottime); /* Tell kernel about boottime */ 122433d6423SLionel Sambuc if (s != OK) 123433d6423SLionel Sambuc panic("pm: sys_stime failed: %d", s); 124433d6423SLionel Sambuc 125433d6423SLionel Sambuc return(OK); 126433d6423SLionel Sambuc } 127