1ad2056f2SAlexander Leidinger /* $NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $ */ 2ad2056f2SAlexander Leidinger 3ad2056f2SAlexander Leidinger /*- 4ad2056f2SAlexander Leidinger * Copyright (c) 2001 The NetBSD Foundation, Inc. 5ad2056f2SAlexander Leidinger * All rights reserved. 6ad2056f2SAlexander Leidinger * 7ad2056f2SAlexander Leidinger * This code is derived from software contributed to The NetBSD Foundation 8ad2056f2SAlexander Leidinger * by Emmanuel Dreyfus. 9ad2056f2SAlexander Leidinger * 10ad2056f2SAlexander Leidinger * Redistribution and use in source and binary forms, with or without 11ad2056f2SAlexander Leidinger * modification, are permitted provided that the following conditions 12ad2056f2SAlexander Leidinger * are met: 13ad2056f2SAlexander Leidinger * 1. Redistributions of source code must retain the above copyright 14ad2056f2SAlexander Leidinger * notice, this list of conditions and the following disclaimer. 15ad2056f2SAlexander Leidinger * 2. Redistributions in binary form must reproduce the above copyright 16ad2056f2SAlexander Leidinger * notice, this list of conditions and the following disclaimer in the 17ad2056f2SAlexander Leidinger * documentation and/or other materials provided with the distribution. 18ad2056f2SAlexander Leidinger * 3. All advertising materials mentioning features or use of this software 19ad2056f2SAlexander Leidinger * must display the following acknowledgement: 20ad2056f2SAlexander Leidinger * This product includes software developed by the NetBSD 21ad2056f2SAlexander Leidinger * Foundation, Inc. and its contributors. 22ad2056f2SAlexander Leidinger * 4. Neither the name of The NetBSD Foundation nor the names of its 23ad2056f2SAlexander Leidinger * contributors may be used to endorse or promote products derived 24ad2056f2SAlexander Leidinger * from this software without specific prior written permission. 25ad2056f2SAlexander Leidinger * 26ad2056f2SAlexander Leidinger * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27ad2056f2SAlexander Leidinger * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28ad2056f2SAlexander Leidinger * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29ad2056f2SAlexander Leidinger * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30ad2056f2SAlexander Leidinger * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31ad2056f2SAlexander Leidinger * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32ad2056f2SAlexander Leidinger * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33ad2056f2SAlexander Leidinger * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34ad2056f2SAlexander Leidinger * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35ad2056f2SAlexander Leidinger * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36ad2056f2SAlexander Leidinger * POSSIBILITY OF SUCH DAMAGE. 37ad2056f2SAlexander Leidinger */ 38ad2056f2SAlexander Leidinger 39ad2056f2SAlexander Leidinger #include <sys/cdefs.h> 40ad2056f2SAlexander Leidinger __FBSDID("$FreeBSD$"); 41ad2056f2SAlexander Leidinger #if 0 42ad2056f2SAlexander Leidinger __KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $"); 43ad2056f2SAlexander Leidinger #endif 44ad2056f2SAlexander Leidinger 45ad2056f2SAlexander Leidinger #include "opt_compat.h" 46ad2056f2SAlexander Leidinger 47ad2056f2SAlexander Leidinger #include <sys/param.h> 48ad2056f2SAlexander Leidinger #include <sys/ucred.h> 49ad2056f2SAlexander Leidinger #include <sys/mount.h> 50ad2056f2SAlexander Leidinger #include <sys/signal.h> 51ad2056f2SAlexander Leidinger #include <sys/stdint.h> 52ad2056f2SAlexander Leidinger #include <sys/syscallsubr.h> 53ad2056f2SAlexander Leidinger #include <sys/sysproto.h> 54ad2056f2SAlexander Leidinger #include <sys/time.h> 55ad2056f2SAlexander Leidinger #include <sys/systm.h> 56ad2056f2SAlexander Leidinger #include <sys/proc.h> 57ad2056f2SAlexander Leidinger 58ad2056f2SAlexander Leidinger #ifdef COMPAT_LINUX32 59ad2056f2SAlexander Leidinger #include <machine/../linux32/linux.h> 60ad2056f2SAlexander Leidinger #include <machine/../linux32/linux32_proto.h> 61ad2056f2SAlexander Leidinger #else 62ad2056f2SAlexander Leidinger #include <machine/../linux/linux.h> 63ad2056f2SAlexander Leidinger #include <machine/../linux/linux_proto.h> 64ad2056f2SAlexander Leidinger #endif 65ad2056f2SAlexander Leidinger 66ad2056f2SAlexander Leidinger static void native_to_linux_timespec(struct l_timespec *, 67ad2056f2SAlexander Leidinger struct timespec *); 68ad2056f2SAlexander Leidinger static void linux_to_native_timespec(struct timespec *, 69ad2056f2SAlexander Leidinger struct l_timespec *); 70ad2056f2SAlexander Leidinger static int linux_to_native_clockid(clockid_t *, clockid_t); 71ad2056f2SAlexander Leidinger 72ad2056f2SAlexander Leidinger static void 73ad2056f2SAlexander Leidinger native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp) 74ad2056f2SAlexander Leidinger { 75ad2056f2SAlexander Leidinger ltp->tv_sec = ntp->tv_sec; 76ad2056f2SAlexander Leidinger ltp->tv_nsec = ntp->tv_nsec; 77ad2056f2SAlexander Leidinger } 78ad2056f2SAlexander Leidinger 79ad2056f2SAlexander Leidinger static void 80ad2056f2SAlexander Leidinger linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp) 81ad2056f2SAlexander Leidinger { 82ad2056f2SAlexander Leidinger ntp->tv_sec = ltp->tv_sec; 83ad2056f2SAlexander Leidinger ntp->tv_nsec = ltp->tv_nsec; 84ad2056f2SAlexander Leidinger } 85ad2056f2SAlexander Leidinger 86ad2056f2SAlexander Leidinger static int 87ad2056f2SAlexander Leidinger linux_to_native_clockid(clockid_t *n, clockid_t l) 88ad2056f2SAlexander Leidinger { 89ad2056f2SAlexander Leidinger switch (l) { 90ad2056f2SAlexander Leidinger case LINUX_CLOCK_REALTIME: 91ad2056f2SAlexander Leidinger *n = CLOCK_REALTIME; 92ad2056f2SAlexander Leidinger break; 93ad2056f2SAlexander Leidinger case LINUX_CLOCK_MONOTONIC: 94ad2056f2SAlexander Leidinger *n = CLOCK_MONOTONIC; 95ad2056f2SAlexander Leidinger break; 96ad2056f2SAlexander Leidinger case LINUX_CLOCK_PROCESS_CPUTIME_ID: 97ad2056f2SAlexander Leidinger case LINUX_CLOCK_THREAD_CPUTIME_ID: 98ad2056f2SAlexander Leidinger case LINUX_CLOCK_REALTIME_HR: 99ad2056f2SAlexander Leidinger case LINUX_CLOCK_MONOTONIC_HR: 100ad2056f2SAlexander Leidinger return EINVAL; 101ad2056f2SAlexander Leidinger } 102ad2056f2SAlexander Leidinger 103ad2056f2SAlexander Leidinger return 0; 104ad2056f2SAlexander Leidinger } 105ad2056f2SAlexander Leidinger 106ad2056f2SAlexander Leidinger int 107ad2056f2SAlexander Leidinger linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args) 108ad2056f2SAlexander Leidinger { 109ad2056f2SAlexander Leidinger struct l_timespec lts; 110ad2056f2SAlexander Leidinger int error; 111ad2056f2SAlexander Leidinger clockid_t nwhich = 0; /* XXX: GCC */ 112ad2056f2SAlexander Leidinger struct timespec tp; 113ad2056f2SAlexander Leidinger 114ad2056f2SAlexander Leidinger error = linux_to_native_clockid(&nwhich, args->which); 115ad2056f2SAlexander Leidinger if (error != 0) 116ad2056f2SAlexander Leidinger return error; 117ad2056f2SAlexander Leidinger 118ad2056f2SAlexander Leidinger error = kern_clock_gettime(td, nwhich, &tp); 119ad2056f2SAlexander Leidinger if (error != 0) 120ad2056f2SAlexander Leidinger return error; 121ad2056f2SAlexander Leidinger 122ad2056f2SAlexander Leidinger native_to_linux_timespec(<s, &tp); 123ad2056f2SAlexander Leidinger 124ad2056f2SAlexander Leidinger return copyout(<s, args->tp, sizeof lts); 125ad2056f2SAlexander Leidinger } 126ad2056f2SAlexander Leidinger 127ad2056f2SAlexander Leidinger int 128ad2056f2SAlexander Leidinger linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args) 129ad2056f2SAlexander Leidinger { 130ad2056f2SAlexander Leidinger struct timespec ts; 131ad2056f2SAlexander Leidinger struct l_timespec lts; 132ad2056f2SAlexander Leidinger int error; 133ad2056f2SAlexander Leidinger clockid_t nwhich = 0; /* XXX: GCC */ 134ad2056f2SAlexander Leidinger 135ad2056f2SAlexander Leidinger error = linux_to_native_clockid(&nwhich, args->which); 136ad2056f2SAlexander Leidinger if (error != 0) 137ad2056f2SAlexander Leidinger return error; 138ad2056f2SAlexander Leidinger 139ad2056f2SAlexander Leidinger error = copyin(args->tp, <s, sizeof lts); 140ad2056f2SAlexander Leidinger if (error != 0) 141ad2056f2SAlexander Leidinger return error; 142ad2056f2SAlexander Leidinger 143ad2056f2SAlexander Leidinger linux_to_native_timespec(&ts, <s); 144ad2056f2SAlexander Leidinger 145ad2056f2SAlexander Leidinger return kern_clock_settime(td, nwhich, &ts); 146ad2056f2SAlexander Leidinger } 147ad2056f2SAlexander Leidinger 148ad2056f2SAlexander Leidinger int 149ad2056f2SAlexander Leidinger linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args) 150ad2056f2SAlexander Leidinger { 151ad2056f2SAlexander Leidinger struct timespec ts; 152ad2056f2SAlexander Leidinger struct l_timespec lts; 153ad2056f2SAlexander Leidinger int error; 154ad2056f2SAlexander Leidinger clockid_t nwhich = 0; /* XXX: GCC */ 155ad2056f2SAlexander Leidinger 156ad2056f2SAlexander Leidinger if (args->tp == NULL) 157ad2056f2SAlexander Leidinger return (0); 158ad2056f2SAlexander Leidinger 159ad2056f2SAlexander Leidinger error = linux_to_native_clockid(&nwhich, args->which); 160ad2056f2SAlexander Leidinger if (error != 0) 161ad2056f2SAlexander Leidinger return error; 162ad2056f2SAlexander Leidinger 163ad2056f2SAlexander Leidinger error = kern_clock_getres(td, nwhich, &ts); 164ad2056f2SAlexander Leidinger if (error != 0) 165ad2056f2SAlexander Leidinger return error; 166ad2056f2SAlexander Leidinger 167ad2056f2SAlexander Leidinger native_to_linux_timespec(<s, &ts); 168ad2056f2SAlexander Leidinger 169ad2056f2SAlexander Leidinger return copyout(<s, args->tp, sizeof lts); 170ad2056f2SAlexander Leidinger } 171ad2056f2SAlexander Leidinger 172ad2056f2SAlexander Leidinger int 173ad2056f2SAlexander Leidinger linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args) 174ad2056f2SAlexander Leidinger { 175ad2056f2SAlexander Leidinger struct timespec *rmtp; 176ad2056f2SAlexander Leidinger struct l_timespec lrqts, lrmts; 177ad2056f2SAlexander Leidinger struct timespec rqts, rmts; 178ad2056f2SAlexander Leidinger int error; 179ad2056f2SAlexander Leidinger 180ad2056f2SAlexander Leidinger if (args->flags != 0) 181ad2056f2SAlexander Leidinger return EINVAL; /* XXX deal with TIMER_ABSTIME */ 182ad2056f2SAlexander Leidinger 183ad2056f2SAlexander Leidinger if (args->which != LINUX_CLOCK_REALTIME) 184ad2056f2SAlexander Leidinger return EINVAL; 185ad2056f2SAlexander Leidinger 186ad2056f2SAlexander Leidinger error = copyin(args->rqtp, &lrqts, sizeof lrqts); 187ad2056f2SAlexander Leidinger if (error != 0) 188ad2056f2SAlexander Leidinger return error; 189ad2056f2SAlexander Leidinger 190ad2056f2SAlexander Leidinger if (args->rmtp != NULL) 191ad2056f2SAlexander Leidinger rmtp = &rmts; 192ad2056f2SAlexander Leidinger else 193ad2056f2SAlexander Leidinger rmtp = NULL; 194ad2056f2SAlexander Leidinger 195ad2056f2SAlexander Leidinger linux_to_native_timespec(&rqts, &lrqts); 196ad2056f2SAlexander Leidinger 197ad2056f2SAlexander Leidinger error = kern_nanosleep(td, &rqts, rmtp); 198ad2056f2SAlexander Leidinger if (error != 0) 199ad2056f2SAlexander Leidinger return error; 200ad2056f2SAlexander Leidinger if (args->rmtp != NULL) { 201ad2056f2SAlexander Leidinger native_to_linux_timespec(&lrmts, rmtp); 202ad2056f2SAlexander Leidinger error = copyout(&lrmts, args->rmtp, sizeof lrmts ); 203ad2056f2SAlexander Leidinger if (error != 0) 204ad2056f2SAlexander Leidinger return error; 205ad2056f2SAlexander Leidinger } 206ad2056f2SAlexander Leidinger 207ad2056f2SAlexander Leidinger return 0; 208ad2056f2SAlexander Leidinger } 209