From 8a3c27fbf728c68eb00852f9f6a681e5ed20ed83 Mon Sep 17 00:00:00 2001 From: bjh21 Date: Wed, 23 Jan 2002 15:52:58 +0000 Subject: [PATCH] Add support for the ARM-specific syscalls in ARMLinux. These are invoked by SWI numbers above 0x9f0000, but we re-map them down to somewhere just after the end of the usual syscall range, since NetBSD doesn't handle sparse syscall arrays well. The only syscall I've actually implemented in this range is cacheflush(), which was previously being mapped to fork(), causing ... interesting results. --- sys/arch/arm/arm/linux_syscall.c | 14 ++++- sys/compat/linux/arch/arm/files.linux_arm | 5 +- sys/compat/linux/arch/arm/linux_sys_machdep.c | 58 +++++++++++++++++++ sys/compat/linux/arch/arm/syscalls.master | 51 +++++++++++++++- 4 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 sys/compat/linux/arch/arm/linux_sys_machdep.c diff --git a/sys/arch/arm/arm/linux_syscall.c b/sys/arch/arm/arm/linux_syscall.c index 9f41916aed26..6bc44d756732 100644 --- a/sys/arch/arm/arm/linux_syscall.c +++ b/sys/arch/arm/arm/linux_syscall.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_syscall.c,v 1.1 2002/01/17 17:26:03 bjh21 Exp $ */ +/* $NetBSD: linux_syscall.c,v 1.2 2002/01/23 15:52:58 bjh21 Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -79,7 +79,7 @@ #include -__RCSID("$NetBSD: linux_syscall.c,v 1.1 2002/01/17 17:26:03 bjh21 Exp $"); +__RCSID("$NetBSD: linux_syscall.c,v 1.2 2002/01/23 15:52:58 bjh21 Exp $"); #include #include @@ -102,6 +102,10 @@ __RCSID("$NetBSD: linux_syscall.c,v 1.1 2002/01/17 17:26:03 bjh21 Exp $"); #include #include +/* ARMLinux has some system calls of its very own. */ +#define LINUX_ARM_NR_BASE 0x9f0000 +#define LINUX_SYS_ARMBASE 0x000100 /* Must agree with syscalls.master */ + void linux_syscall(trapframe_t *frame, struct proc *p, u_int32_t insn) { @@ -110,7 +114,11 @@ linux_syscall(trapframe_t *frame, struct proc *p, u_int32_t insn) u_int nargs; register_t *args, rval[2]; - code = insn & (LINUX_SYS_NSYSENT - 1); + code = insn & 0x00ffffff; + /* Remap ARM-specific syscalls onto the end of the standard range. */ + if (code > LINUX_ARM_NR_BASE) + code = code - LINUX_ARM_NR_BASE + LINUX_SYS_ARMBASE; + code &= LINUX_SYS_NSYSENT - 1; /* Linux passes all arguments in order in registers, which is nice. */ args = &frame->tf_r0; diff --git a/sys/compat/linux/arch/arm/files.linux_arm b/sys/compat/linux/arch/arm/files.linux_arm index 704b858d0e0a..db2efee26a62 100644 --- a/sys/compat/linux/arch/arm/files.linux_arm +++ b/sys/compat/linux/arch/arm/files.linux_arm @@ -1,10 +1,11 @@ -# $NetBSD: files.linux_arm,v 1.1 2002/01/14 23:14:35 bjh21 Exp $ +# $NetBSD: files.linux_arm,v 1.2 2002/01/23 15:52:59 bjh21 Exp $ # -# Config file description for arm-dependent Linux compat code. +# Config file description for ARM-dependent Linux compat code. file compat/linux/arch/arm/linux_machdep.c compat_linux file compat/linux/arch/arm/linux_ptrace.c compat_linux file compat/linux/arch/arm/linux_syscalls.c compat_linux file compat/linux/arch/arm/linux_sysent.c compat_linux +file compat/linux/arch/arm/linux_sys_machdep.c compat_linux file compat/linux/arch/arm/linux_sigarray.c compat_linux file compat/linux/arch/arm/linux_commons.c compat_linux diff --git a/sys/compat/linux/arch/arm/linux_sys_machdep.c b/sys/compat/linux/arch/arm/linux_sys_machdep.c new file mode 100644 index 000000000000..f4fd8e041c73 --- /dev/null +++ b/sys/compat/linux/arch/arm/linux_sys_machdep.c @@ -0,0 +1,58 @@ +/* $NetBSD: linux_sys_machdep.c,v 1.1 2002/01/23 15:52:59 bjh21 Exp $ */ + +/*- + * Copyright (c) 2002 Ben Harris + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +__RCSID("$Id: linux_sys_machdep.c,v 1.1 2002/01/23 15:52:59 bjh21 Exp $"); + +#include + +#include +#include +#include +#include +#include + +#include + +int +linux_sys_cacheflush(struct proc *p, void *v, register_t *retval) +{ + struct linux_sys_cacheflush_args /* { + syscallarg(uintptr_t) from; + syscallarg(uintptr_t) to; + } */ *uap = v; + +#ifndef arm26 + cpu_cache_syncI_rng(SCARG(uap, from), + SCARG(uap, to) - SCARG(uap, from) + 1); +#endif + *retval = 0; + return 0; +} diff --git a/sys/compat/linux/arch/arm/syscalls.master b/sys/compat/linux/arch/arm/syscalls.master index 66321a5744d1..6893b637dff4 100644 --- a/sys/compat/linux/arch/arm/syscalls.master +++ b/sys/compat/linux/arch/arm/syscalls.master @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.2 2002/01/15 10:21:46 bjh21 Exp $ + $NetBSD: syscalls.master,v 1.3 2002/01/23 15:52:59 bjh21 Exp $ ; Derived from sys/compat/linux/arch/*/syscalls.master ; and from Linux 2.4.12 arch/arm/kernel/calls.S @@ -368,3 +368,52 @@ 219 UNIMPL mincore 220 UNIMPL madvise 221 UNIMPL fcntl64 +; Fill until 256 +222 UNIMPL +223 UNIMPL +224 UNIMPL +225 UNIMPL +226 UNIMPL +227 UNIMPL +228 UNIMPL +229 UNIMPL +230 UNIMPL +231 UNIMPL +232 UNIMPL +233 UNIMPL +234 UNIMPL +235 UNIMPL +236 UNIMPL +237 UNIMPL +238 UNIMPL +239 UNIMPL +240 UNIMPL +241 UNIMPL +242 UNIMPL +243 UNIMPL +244 UNIMPL +245 UNIMPL +246 UNIMPL +247 UNIMPL +248 UNIMPL +249 UNIMPL +250 UNIMPL +251 UNIMPL +252 UNIMPL +253 UNIMPL +254 UNIMPL +255 UNIMPL + +; ARMLinux actually has two ranges of syscalls. Normal syscalls use +; SWI numbers starting at 0x900000 (__NR_SYSCALL_BASE). Special +; ARM-specific syscalls use SWI numbers starting at 0x9f00000 +; (__ARM_NR_BASE). linux_syscall() (in arch/arm/arm/linux_syscall.c) +; remaps these down to 0x900100 so that we can use one linux_sysent +; array for the whole lot. + +256 UNIMPL +257 UNIMPL breakpoint +258 STD { int linux_sys_cacheflush(uintptr_t from, \ + intptr_t to); } +259 UNIMPL usr26 +260 UNIMPL usr32