xref: /freebsd/sys/kern/p1003_1b.c (revision e84b7987bc37292885343916731d8b1c41eee44a)
18a6472b7SPeter Dufault /*
28a6472b7SPeter Dufault  * Copyright (c) 1996, 1997, 1998
38a6472b7SPeter Dufault  *	HD Associates, Inc.  All rights reserved.
48a6472b7SPeter Dufault  *
58a6472b7SPeter Dufault  * Redistribution and use in source and binary forms, with or without
68a6472b7SPeter Dufault  * modification, are permitted provided that the following conditions
78a6472b7SPeter Dufault  * are met:
88a6472b7SPeter Dufault  * 1. Redistributions of source code must retain the above copyright
98a6472b7SPeter Dufault  *    notice, this list of conditions and the following disclaimer.
108a6472b7SPeter Dufault  * 2. Redistributions in binary form must reproduce the above copyright
118a6472b7SPeter Dufault  *    notice, this list of conditions and the following disclaimer in the
128a6472b7SPeter Dufault  *    documentation and/or other materials provided with the distribution.
138a6472b7SPeter Dufault  * 3. All advertising materials mentioning features or use of this software
148a6472b7SPeter Dufault  *    must display the following acknowledgement:
158a6472b7SPeter Dufault  *	This product includes software developed by HD Associates, Inc
168a6472b7SPeter Dufault  * 4. Neither the name of the author nor the names of any co-contributors
178a6472b7SPeter Dufault  *    may be used to endorse or promote products derived from this software
188a6472b7SPeter Dufault  *    without specific prior written permission.
198a6472b7SPeter Dufault  *
208a6472b7SPeter Dufault  * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND
218a6472b7SPeter Dufault  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
228a6472b7SPeter Dufault  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
238a6472b7SPeter Dufault  * ARE DISCLAIMED.  IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
248a6472b7SPeter Dufault  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
258a6472b7SPeter Dufault  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
268a6472b7SPeter Dufault  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
278a6472b7SPeter Dufault  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
288a6472b7SPeter Dufault  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
298a6472b7SPeter Dufault  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
308a6472b7SPeter Dufault  * SUCH DAMAGE.
318a6472b7SPeter Dufault  *
32365c5db0SPeter Wemm  * $FreeBSD$
338a6472b7SPeter Dufault  */
348a6472b7SPeter Dufault 
358a6472b7SPeter Dufault /* p1003_1b: Real Time common code.
368a6472b7SPeter Dufault  */
378a6472b7SPeter Dufault 
388a6472b7SPeter Dufault #include <sys/param.h>
398a6472b7SPeter Dufault #include <sys/systm.h>
408a6472b7SPeter Dufault #include <sys/kernel.h>
41fb919e4dSMark Murray #include <sys/lock.h>
428a6472b7SPeter Dufault #include <sys/module.h>
43fb919e4dSMark Murray #include <sys/mutex.h>
44fb919e4dSMark Murray #include <sys/proc.h>
458a6472b7SPeter Dufault #include <sys/sysctl.h>
46fb919e4dSMark Murray #include <sys/sysent.h>
47fb919e4dSMark Murray #include <sys/syslog.h>
48fb919e4dSMark Murray #include <sys/sysproto.h>
498a6472b7SPeter Dufault 
508a6472b7SPeter Dufault #include <posix4/posix4.h>
518a6472b7SPeter Dufault 
528a6472b7SPeter Dufault MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B");
538a6472b7SPeter Dufault 
542a61a110SPeter Dufault /* The system calls return ENOSYS if an entry is called that is
552a61a110SPeter Dufault  * not run-time supported.  I am also logging since some programs
562a61a110SPeter Dufault  * start to use this when they shouldn't.  That will be removed if annoying.
572a61a110SPeter Dufault  */
588a6472b7SPeter Dufault int
598a6472b7SPeter Dufault syscall_not_present(struct proc *p, const char *s, struct nosys_args *uap)
608a6472b7SPeter Dufault {
618a6472b7SPeter Dufault 	log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n",
628a6472b7SPeter Dufault 			p->p_comm, p->p_pid, s);
632a61a110SPeter Dufault 
642a61a110SPeter Dufault 	/* a " return nosys(p, uap); " here causes a core dump.
652a61a110SPeter Dufault 	 */
662a61a110SPeter Dufault 
672a61a110SPeter Dufault 	return ENOSYS;
688a6472b7SPeter Dufault }
698a6472b7SPeter Dufault 
708a6472b7SPeter Dufault #if !defined(_KPOSIX_PRIORITY_SCHEDULING)
718a6472b7SPeter Dufault 
72e9189611SPeter Wemm /* Not configured but loadable via a module:
738a6472b7SPeter Dufault  */
748a6472b7SPeter Dufault 
758a6472b7SPeter Dufault static int sched_attach(void)
768a6472b7SPeter Dufault {
778a6472b7SPeter Dufault 	return 0;
788a6472b7SPeter Dufault }
798a6472b7SPeter Dufault 
808a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setparam)
818a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getparam)
828a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_setscheduler)
838a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_getscheduler)
848a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_yield)
858a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_max)
868a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_get_priority_min)
878a6472b7SPeter Dufault SYSCALL_NOT_PRESENT_GEN(sched_rr_get_interval)
888a6472b7SPeter Dufault 
898a6472b7SPeter Dufault #else
908a6472b7SPeter Dufault 
918a6472b7SPeter Dufault /* Configured in kernel version:
928a6472b7SPeter Dufault  */
938a6472b7SPeter Dufault static struct ksched *ksched;
948a6472b7SPeter Dufault 
958a6472b7SPeter Dufault static int sched_attach(void)
968a6472b7SPeter Dufault {
978a6472b7SPeter Dufault 	int ret = ksched_attach(&ksched);
988a6472b7SPeter Dufault 
998a6472b7SPeter Dufault 	if (ret == 0)
1008a6472b7SPeter Dufault 		p31b_setcfg(CTL_P1003_1B_PRIORITY_SCHEDULING, 1);
1018a6472b7SPeter Dufault 
1028a6472b7SPeter Dufault 	return ret;
1038a6472b7SPeter Dufault }
1048a6472b7SPeter Dufault 
1058a6472b7SPeter Dufault int sched_setparam(struct proc *p,
1068a6472b7SPeter Dufault 	struct sched_setparam_args *uap)
1078a6472b7SPeter Dufault {
1081af55356SRobert Watson 	struct proc *targetp;
1098a6472b7SPeter Dufault 	int e;
1108a6472b7SPeter Dufault 
111aebde782SPeter Dufault 	struct sched_param sched_param;
112e8f7a952SRobert Watson 	e = copyin(uap->param, &sched_param, sizeof(sched_param));
113e8f7a952SRobert Watson 	if (e)
114e8f7a952SRobert Watson 		return (e);
115aebde782SPeter Dufault 
116e84b7987SRobert Watson 	if (uap->pid == 0) {
117e84b7987SRobert Watson 		targetp = p;
118e84b7987SRobert Watson 		PROC_LOCK(targetp);
119e84b7987SRobert Watson 	} else {
120e84b7987SRobert Watson 		targetp = pfind(uap->pid);
121e84b7987SRobert Watson 		if (targetp == NULL)
122e84b7987SRobert Watson 			return (ESRCH);
123e84b7987SRobert Watson 	}
124e84b7987SRobert Watson 
125e84b7987SRobert Watson 	e = p_can(p, targetp, P_CAN_SCHED, NULL);
126e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
12764e55bf4SRobert Watson 	if (e)
12864e55bf4SRobert Watson 		return (e);
129e84b7987SRobert Watson 
1301af55356SRobert Watson 	e = ksched_setparam(&p->p_retval[0], ksched, targetp,
13164e55bf4SRobert Watson 		(const struct sched_param *)&sched_param);
13264e55bf4SRobert Watson 	return (e);
1338a6472b7SPeter Dufault }
1348a6472b7SPeter Dufault 
1358a6472b7SPeter Dufault int sched_getparam(struct proc *p,
1368a6472b7SPeter Dufault 	struct sched_getparam_args *uap)
1378a6472b7SPeter Dufault {
1388a6472b7SPeter Dufault 	int e;
139aebde782SPeter Dufault 	struct sched_param sched_param;
1401af55356SRobert Watson 	struct proc *targetp;
1418a6472b7SPeter Dufault 
142e84b7987SRobert Watson 	if (uap->pid == 0) {
143e84b7987SRobert Watson 		targetp = p;
144e84b7987SRobert Watson 		PROC_LOCK(targetp);
145e84b7987SRobert Watson 	} else {
146e84b7987SRobert Watson 		targetp = pfind(uap->pid);
147e84b7987SRobert Watson 		if (targetp == NULL)
148e84b7987SRobert Watson 			return (ESRCH);
149e84b7987SRobert Watson 	}
150e84b7987SRobert Watson 
151e84b7987SRobert Watson 	e = p_can(p, targetp, P_CAN_SEE, NULL);
152e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
15364e55bf4SRobert Watson 	if (e)
15464e55bf4SRobert Watson 		return (e);
155e84b7987SRobert Watson 
1561af55356SRobert Watson 	e = ksched_getparam(&p->p_retval[0], ksched, targetp, &sched_param);
15764e55bf4SRobert Watson 	if (e)
15864e55bf4SRobert Watson 		return (e);
1598a6472b7SPeter Dufault 
16064e55bf4SRobert Watson 	e = copyout(&sched_param, uap->param, sizeof(sched_param));
16164e55bf4SRobert Watson 	return (e);
1628a6472b7SPeter Dufault }
1638a6472b7SPeter Dufault int sched_setscheduler(struct proc *p,
1648a6472b7SPeter Dufault 	struct sched_setscheduler_args *uap)
1658a6472b7SPeter Dufault {
1668a6472b7SPeter Dufault 	int e;
167aebde782SPeter Dufault 	struct sched_param sched_param;
1681af55356SRobert Watson 	struct proc *targetp;
1691af55356SRobert Watson 
170e8f7a952SRobert Watson 	e = copyin(uap->param, &sched_param, sizeof(sched_param));
171e8f7a952SRobert Watson 	if (e)
172e8f7a952SRobert Watson 		return (e);
173aebde782SPeter Dufault 
174e84b7987SRobert Watson 	if (uap->pid == 0) {
175e84b7987SRobert Watson 		targetp = p;
176e84b7987SRobert Watson 		PROC_LOCK(targetp);
177e84b7987SRobert Watson 	} else {
178e84b7987SRobert Watson 		targetp = pfind(uap->pid);
179e84b7987SRobert Watson 		if (targetp == NULL)
180e84b7987SRobert Watson 			return (ESRCH);
181e84b7987SRobert Watson 	}
182e84b7987SRobert Watson 
183e84b7987SRobert Watson 	e = p_can(p, targetp, P_CAN_SCHED, NULL);
184e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
18564e55bf4SRobert Watson 	if (e)
18664e55bf4SRobert Watson 		return (e);
187e84b7987SRobert Watson 
1881af55356SRobert Watson 	e = ksched_setscheduler(&p->p_retval[0], ksched, targetp, uap->policy,
18964e55bf4SRobert Watson 		(const struct sched_param *)&sched_param);
1908a6472b7SPeter Dufault 
19164e55bf4SRobert Watson 	return (e);
1928a6472b7SPeter Dufault }
1938a6472b7SPeter Dufault int sched_getscheduler(struct proc *p,
1948a6472b7SPeter Dufault 	struct sched_getscheduler_args *uap)
1958a6472b7SPeter Dufault {
1968a6472b7SPeter Dufault 	int e;
1971af55356SRobert Watson 	struct proc *targetp;
1988a6472b7SPeter Dufault 
199e84b7987SRobert Watson 	if (uap->pid == 0) {
200e84b7987SRobert Watson 		targetp = p;
201e84b7987SRobert Watson 		PROC_LOCK(targetp);
202e84b7987SRobert Watson 	} else {
203e84b7987SRobert Watson 		targetp = pfind(uap->pid);
204e84b7987SRobert Watson 		if (targetp == NULL)
205e84b7987SRobert Watson 			return (ESRCH);
206e84b7987SRobert Watson 	}
207e84b7987SRobert Watson 
208e84b7987SRobert Watson 	e = p_can(p, targetp, P_CAN_SEE, NULL);
209e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
21064e55bf4SRobert Watson 	if (e)
21164e55bf4SRobert Watson 		return (e);
212e84b7987SRobert Watson 
2131af55356SRobert Watson 	e = ksched_getscheduler(&p->p_retval[0], ksched, targetp);
21464e55bf4SRobert Watson 
21564e55bf4SRobert Watson 	return (e);
2168a6472b7SPeter Dufault }
2178a6472b7SPeter Dufault int sched_yield(struct proc *p,
2188a6472b7SPeter Dufault 	struct sched_yield_args *uap)
2198a6472b7SPeter Dufault {
2208a6472b7SPeter Dufault 	return ksched_yield(&p->p_retval[0], ksched);
2218a6472b7SPeter Dufault }
2228a6472b7SPeter Dufault int sched_get_priority_max(struct proc *p,
2238a6472b7SPeter Dufault 	struct sched_get_priority_max_args *uap)
2248a6472b7SPeter Dufault {
2258a6472b7SPeter Dufault 	return ksched_get_priority_max(&p->p_retval[0],
2268a6472b7SPeter Dufault 	ksched, uap->policy);
2278a6472b7SPeter Dufault }
2288a6472b7SPeter Dufault int sched_get_priority_min(struct proc *p,
2298a6472b7SPeter Dufault 	struct sched_get_priority_min_args *uap)
2308a6472b7SPeter Dufault {
2318a6472b7SPeter Dufault 	return ksched_get_priority_min(&p->p_retval[0],
2328a6472b7SPeter Dufault 	ksched, uap->policy);
2338a6472b7SPeter Dufault }
2348a6472b7SPeter Dufault int sched_rr_get_interval(struct proc *p,
2358a6472b7SPeter Dufault 	struct sched_rr_get_interval_args *uap)
2368a6472b7SPeter Dufault {
2378a6472b7SPeter Dufault 	int e;
2381af55356SRobert Watson 	struct proc *targetp;
2398a6472b7SPeter Dufault 
240e84b7987SRobert Watson 	if (uap->pid == 0) {
241e84b7987SRobert Watson 		targetp = p;
242e84b7987SRobert Watson 		PROC_LOCK(targetp);
243e84b7987SRobert Watson 	} else {
244e84b7987SRobert Watson 		targetp = pfind(uap->pid);
245e84b7987SRobert Watson 		if (targetp == NULL)
246e84b7987SRobert Watson 			return (ESRCH);
247e84b7987SRobert Watson 	}
248e84b7987SRobert Watson 
249e84b7987SRobert Watson 	e = p_can(p, targetp, P_CAN_SEE, NULL);
250e84b7987SRobert Watson 	PROC_UNLOCK(targetp);
25164e55bf4SRobert Watson 	if (e)
25264e55bf4SRobert Watson 		return (e);
253e84b7987SRobert Watson 
2541af55356SRobert Watson 	e = ksched_rr_get_interval(&p->p_retval[0], ksched, targetp,
2551af55356SRobert Watson 	    uap->interval);
2568a6472b7SPeter Dufault 
25764e55bf4SRobert Watson 	return (e);
2588a6472b7SPeter Dufault }
2598a6472b7SPeter Dufault 
2608a6472b7SPeter Dufault #endif
2618a6472b7SPeter Dufault 
2628a6472b7SPeter Dufault static void p31binit(void *notused)
2638a6472b7SPeter Dufault {
2648a6472b7SPeter Dufault 	(void) sched_attach();
265ce47711dSPeter Dufault 	p31b_setcfg(CTL_P1003_1B_PAGESIZE, PAGE_SIZE);
2668a6472b7SPeter Dufault }
2678a6472b7SPeter Dufault 
2688a6472b7SPeter Dufault SYSINIT(p31b, SI_SUB_P1003_1B, SI_ORDER_FIRST, p31binit, NULL);
269