File: [local] / sys / compat / common / kern_ipc_35.c (download)
Revision 1.1.1.1 (vendor branch), Tue Mar 4 16:09:06 2008 UTC (16 years, 6 months ago) by nbrk
Branch: OPENBSD_4_2_BASE, MAIN
CVS Tags: jornada-partial-support-wip, HEAD Changes since 1.1: +0 -0 lines
Import of OpenBSD 4.2 release kernel tree with initial code to support
Jornada 720/728, StrongARM 1110-based handheld PC.
At this point kernel roots on NFS and boots into vfs_mountroot() and traps.
What is supported:
- glass console, Jornada framebuffer (jfb) works in 16bpp direct color mode
(needs some palette tweaks for non black/white/blue colors, i think)
- saic, SA11x0 interrupt controller (needs cleanup)
- sacom, SA11x0 UART (supported only as boot console for now)
- SA11x0 GPIO controller fully supported (but can't handle multiple interrupt
handlers on one gpio pin)
- sassp, SSP port on SA11x0 that attaches spibus
- Jornada microcontroller (jmcu) to control kbd, battery, etc throught
the SPI bus (wskbd attaches on jmcu, but not tested)
- tod functions seem work
- initial code for SA-1111 (chip companion) : this is TODO
Next important steps, i think:
- gpio and intc on sa1111
- pcmcia support for sa11x0 (and sa1111 help logic)
- REAL root on nfs when we have PCMCIA support (we may use any of supported pccard NICs)
- root on wd0! (using already supported PCMCIA-ATA)
|
/* $OpenBSD: kern_ipc_35.c,v 1.3 2004/07/15 11:00:12 millert Exp $ */
/*
* Copyright (c) 2004 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
#ifdef SYSVMSG
/*
* Old-style shmget(2) used int for the size parameter, we now use size_t.
*/
int
compat_35_sys_shmget(struct proc *p, void *v, register_t *retval)
{
struct compat_35_sys_shmget_args /* {
syscallarg(key_t) key;
syscallarg(int) size;
syscallarg(int) shmflg;
} */ *uap = v;
struct sys_shmget_args /* {
syscallarg(key_t) key;
syscallarg(size_t) size;
syscallarg(int) shmflg;
} */ shmget_args;
SCARG(&shmget_args, key) = SCARG(uap, key);
SCARG(&shmget_args, size) = (size_t)SCARG(uap, size);
SCARG(&shmget_args, shmflg) = SCARG(uap, shmflg);
return (sys_shmget(p, &shmget_args, retval));
}
#endif
#ifdef SYSVSEM
/*
* Old-style shmget(2) used u_int for the nsops parameter, we now use size_t.
*/
int
compat_35_sys_semop(struct proc *p, void *v, register_t *retval)
{
struct compat_35_sys_semop_args /* {
syscallarg(int) semid;
syscallarg(struct sembuf *) sops;
syscallarg(u_int) nsops;
} */ *uap = v;
struct sys_semop_args /* {
syscallarg(int) semid;
syscallarg(struct sembuf *) sops;
syscallarg(size_t) nsops;
} */ semop_args;
SCARG(&semop_args, semid) = SCARG(uap, semid);
SCARG(&semop_args, sops) = SCARG(uap, sops);
SCARG(&semop_args, nsops) = (size_t)SCARG(uap, nsops);
return (sys_semop(p, &semop_args, retval));
}
#endif
/*
* Convert between new and old struct {msq,sem,shm}id_ds (both ways)
*/
#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
#define cvt_ds(to, from, type, base) do { \
(to)->type##_perm.cuid = (from)->type##_perm.cuid; \
(to)->type##_perm.cgid = (from)->type##_perm.cgid; \
(to)->type##_perm.uid = (from)->type##_perm.uid; \
(to)->type##_perm.gid = (from)->type##_perm.gid; \
(to)->type##_perm.mode = (from)->type##_perm.mode & 0xffffU; \
(to)->type##_perm.seq = (from)->type##_perm.seq; \
(to)->type##_perm.key = (from)->type##_perm.key; \
bcopy((caddr_t)&(from)->base, (caddr_t)&(to)->base, \
sizeof(*(to)) - ((caddr_t)&(to)->base - (caddr_t)to)); \
} while (0)
#endif /* SYSVMSG || SYSVSEM || SYSVSHM */
#ifdef SYSVMSG
/*
* Copy a struct msqid_ds35 from userland and convert to struct msqid_ds
*/
static int
msqid_copyin(const void *uaddr, void *kaddr, size_t len)
{
struct msqid_ds *msqbuf = kaddr;
struct msqid_ds35 omsqbuf;
int error;
if (len != sizeof(struct msqid_ds))
return (EFAULT);
if ((error = copyin(uaddr, &omsqbuf, sizeof(omsqbuf))) == 0)
cvt_ds(msqbuf, &omsqbuf, msg, msg_first);
return (error);
}
/*
* Convert a struct msqid_ds to struct msqid_ds35 and copy to userland
*/
static int
msqid_copyout(const void *kaddr, void *uaddr, size_t len)
{
const struct msqid_ds *msqbuf = kaddr;
struct msqid_ds35 omsqbuf;
if (len != sizeof(struct msqid_ds))
return (EFAULT);
cvt_ds(&omsqbuf, msqbuf, msg, msg_first);
return (copyout(&omsqbuf, uaddr, sizeof(omsqbuf)));
}
/*
* OpenBSD 3.5 msgctl(2) with 16bit mode_t in struct ipcperm.
*/
int
compat_35_sys_msgctl(struct proc *p, void *v, register_t *retval)
{
struct compat_35_sys_msgctl_args /* {
syscallarg(int) msqid;
syscallarg(int) cmd;
syscallarg(struct msqid_ds35 *) buf;
} */ *uap = v;
return (msgctl1(p, SCARG(uap, msqid), SCARG(uap, cmd),
(caddr_t)SCARG(uap, buf), msqid_copyin, msqid_copyout));
}
#endif /* SYSVMSG */
#ifdef SYSVSEM
/*
* Copy a struct semid_ds35 from userland and convert to struct semid_ds
*/
static int
semid_copyin(const void *uaddr, void *kaddr, size_t len)
{
struct semid_ds *sembuf = kaddr;
struct semid_ds35 osembuf;
int error;
if (len != sizeof(struct semid_ds))
return (EFAULT);
if ((error = copyin(uaddr, &osembuf, sizeof(osembuf))) == 0)
cvt_ds(sembuf, &osembuf, sem, sem_base);
return (error);
}
/*
* Convert a struct semid_ds to struct semid_ds35 and copy to userland
*/
static int
semid_copyout(const void *kaddr, void *uaddr, size_t len)
{
const struct semid_ds *sembuf = kaddr;
struct semid_ds35 osembuf;
if (len != sizeof(struct semid_ds))
return (EFAULT);
cvt_ds(&osembuf, sembuf, sem, sem_base);
return (copyout(&osembuf, uaddr, sizeof(osembuf)));
}
/*
* OpenBSD 3.5 semctl(2) with 16bit mode_t in struct ipcperm.
*/
int
compat_35_sys___semctl(struct proc *p, void *v, register_t *retval)
{
struct compat_35_sys___semctl_args /* {
syscallarg(int) semid;
syscallarg(int) semnum;
syscallarg(int) cmd;
syscallarg(union semun *) arg;
} */ *uap = v;
union semun arg;
int error = 0, cmd = SCARG(uap, cmd);
switch (cmd) {
case IPC_SET:
case IPC_STAT:
case GETALL:
case SETVAL:
case SETALL:
error = copyin(SCARG(uap, arg), &arg, sizeof(arg));
break;
}
if (error == 0) {
error = semctl1(p, SCARG(uap, semid), SCARG(uap, semnum),
cmd, &arg, retval, semid_copyin, semid_copyout);
}
return (error);
}
#endif /* SYSVSEM */
#ifdef SYSVSHM
/*
* Copy a struct shmid_ds35 from userland and convert to struct shmid_ds
*/
static int
shmid_copyin(const void *uaddr, void *kaddr, size_t len)
{
struct shmid_ds *shmbuf = kaddr;
struct shmid_ds35 oshmbuf;
int error;
if (len != sizeof(struct shmid_ds))
return (EFAULT);
if ((error = copyin(uaddr, &oshmbuf, sizeof(oshmbuf))) == 0)
cvt_ds(shmbuf, &oshmbuf, shm, shm_segsz);
return (error);
}
/*
* Convert a struct shmid_ds to struct shmid_ds35 and copy to userland
*/
static int
shmid_copyout(const void *kaddr, void *uaddr, size_t len)
{
const struct shmid_ds *shmbuf = kaddr;
struct shmid_ds35 oshmbuf;
if (len != sizeof(struct shmid_ds))
return (EFAULT);
cvt_ds(&oshmbuf, shmbuf, shm, shm_segsz);
return (copyout(&oshmbuf, uaddr, sizeof(oshmbuf)));
}
/*
* OpenBSD 3.5 shmctl(2) with 16bit mode_t in struct ipcperm.
*/
int
compat_35_sys_shmctl(struct proc *p, void *v, register_t *retval)
{
struct compat_35_sys_shmctl_args /* {
syscallarg(int) shmid;
syscallarg(int) cmd;
syscallarg(struct shmid_ds35 *) buf;
} */ *uap = v;
return (shmctl1(p, SCARG(uap, shmid), SCARG(uap, cmd),
(caddr_t)SCARG(uap, buf), shmid_copyin, shmid_copyout));
}
#endif /* SYSVSHM */