Module Name: src
Committed By: ryo
Date: Fri Oct 12 01:28:58 UTC 2018
Modified Files:
src/sys/arch/aarch64/aarch64: cpuswitch.S db_disasm.c db_machdep.c
exec_machdep.c fault.c locore.S netbsd32_machdep.c pmap.c trap.c
vectors.S
src/sys/arch/aarch64/conf: files.aarch64
src/sys/arch/aarch64/include: armreg.h db_machdep.h elf_machdep.h
netbsd32_machdep.h param.h pmap.h vmparam.h
src/sys/arch/arm/include: mcontext.h
src/sys/arch/evbarm/conf: GENERIC64 RPI64
Added Files:
src/sys/arch/aarch64/aarch64: aarch32_syscall.c netbsd32_syscall.c
Log Message:
add initial support of COMPAT_NETBSD32 on AArch64.
arm ELF32 EABI binaries could be execute in AArch32 state on AArch64. A32 THUMB
mode is not supported yet.
To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/arch/aarch64/aarch64/aarch32_syscall.c \
src/sys/arch/aarch64/aarch64/netbsd32_syscall.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/aarch64/aarch64/cpuswitch.S \
src/sys/arch/aarch64/aarch64/db_disasm.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/aarch64/aarch64/db_machdep.c \
src/sys/arch/aarch64/aarch64/vectors.S
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/aarch64/aarch64/exec_machdep.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/aarch64/aarch64/fault.c
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/aarch64/aarch64/locore.S \
src/sys/arch/aarch64/aarch64/pmap.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/aarch64/aarch64/netbsd32_machdep.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/aarch64/aarch64/trap.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/aarch64/conf/files.aarch64
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/aarch64/include/armreg.h
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/aarch64/include/db_machdep.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/aarch64/include/elf_machdep.h \
src/sys/arch/aarch64/include/param.h
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/aarch64/include/netbsd32_machdep.h
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/aarch64/include/pmap.h
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/aarch64/include/vmparam.h
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/arm/include/mcontext.h
cvs rdiff -u -r1.43 -r1.44 src/sys/arch/evbarm/conf/GENERIC64
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/conf/RPI64
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/aarch64/aarch64/cpuswitch.S
diff -u src/sys/arch/aarch64/aarch64/cpuswitch.S:1.4 src/sys/arch/aarch64/aarch64/cpuswitch.S:1.5
--- src/sys/arch/aarch64/aarch64/cpuswitch.S:1.4 Tue Jul 17 18:08:36 2018
+++ src/sys/arch/aarch64/aarch64/cpuswitch.S Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuswitch.S,v 1.4 2018/07/17 18:08:36 christos Exp $ */
+/* $NetBSD: cpuswitch.S,v 1.5 2018/10/12 01:28:57 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -33,9 +33,10 @@
#include <aarch64/locore.h>
#include "assym.h"
+#include "opt_compat_netbsd32.h"
#include "opt_ddb.h"
-RCSID("$NetBSD: cpuswitch.S,v 1.4 2018/07/17 18:08:36 christos Exp $")
+RCSID("$NetBSD: cpuswitch.S,v 1.5 2018/10/12 01:28:57 ryo Exp $")
/*
* At IPL_SCHED:
@@ -308,6 +309,9 @@ ENTRY_NP(el0_trap_exit)
ldr x0, [x9, #L_PRIVATE] /* tpidr_el0 = curlwp->l_private */
msr tpidr_el0, x0
+#ifdef COMPAT_NETBSD32
+ msr tpidrro_el0, x0
+#endif
unwind_x3_x30
Index: src/sys/arch/aarch64/aarch64/db_disasm.c
diff -u src/sys/arch/aarch64/aarch64/db_disasm.c:1.4 src/sys/arch/aarch64/aarch64/db_disasm.c:1.5
--- src/sys/arch/aarch64/aarch64/db_disasm.c:1.4 Sat Sep 15 19:47:48 2018
+++ src/sys/arch/aarch64/aarch64/db_disasm.c Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: db_disasm.c,v 1.4 2018/09/15 19:47:48 jakllsch Exp $ */
+/* $NetBSD: db_disasm.c,v 1.5 2018/10/12 01:28:57 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.4 2018/09/15 19:47:48 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_disasm.c,v 1.5 2018/10/12 01:28:57 ryo Exp $");
#include <sys/param.h>
#include <machine/db_machdep.h>
@@ -121,3 +121,18 @@ strdisasm(vaddr_t pc)
return strdisasm_buf;
}
+
+/*
+ * disassemble aarch32 insns?
+ */
+const char *
+strdisasm_aarch32(vaddr_t pc)
+{
+ uint32_t insn = *(uint32_t *)pc;
+
+ /* not supported any aarch32 insns yet... */
+ snprintf(strdisasm_buf, sizeof(strdisasm_buf), ".insn 0x%08x", insn);
+
+ return strdisasm_buf;
+}
+
Index: src/sys/arch/aarch64/aarch64/db_machdep.c
diff -u src/sys/arch/aarch64/aarch64/db_machdep.c:1.8 src/sys/arch/aarch64/aarch64/db_machdep.c:1.9
--- src/sys/arch/aarch64/aarch64/db_machdep.c:1.8 Sat Sep 15 19:47:48 2018
+++ src/sys/arch/aarch64/aarch64/db_machdep.c Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: db_machdep.c,v 1.8 2018/09/15 19:47:48 jakllsch Exp $ */
+/* $NetBSD: db_machdep.c,v 1.9 2018/10/12 01:28:57 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.8 2018/09/15 19:47:48 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.9 2018/10/12 01:28:57 ryo Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_compat_netbsd32.h"
+#endif
#include <sys/param.h>
#include <sys/systm.h>
@@ -180,6 +184,31 @@ db_regs_t ddb_regs;
void
dump_trapframe(struct trapframe *tf, void (*pr)(const char *, ...))
{
+#ifdef COMPAT_NETBSD32
+ if (tf->tf_spsr & SPSR_A32) {
+ (*pr)(" pc=%016"PRIxREGISTER", spsr=%016"PRIxREGISTER
+ " (AArch32)\n", tf->tf_pc, tf->tf_spsr);
+ (*pr)(" esr=%016"PRIxREGISTER", far=%016"PRIxREGISTER"\n",
+ tf->tf_esr, tf->tf_far);
+ (*pr)(" r0=%016"PRIxREGISTER", r1=%016"PRIxREGISTER"\n",
+ tf->tf_reg[0], tf->tf_reg[1]);
+ (*pr)(" r2=%016"PRIxREGISTER", r3=%016"PRIxREGISTER"\n",
+ tf->tf_reg[2], tf->tf_reg[3]);
+ (*pr)(" r4=%016"PRIxREGISTER", r5=%016"PRIxREGISTER"\n",
+ tf->tf_reg[4], tf->tf_reg[5]);
+ (*pr)(" r6=%016"PRIxREGISTER", r7=%016"PRIxREGISTER"\n",
+ tf->tf_reg[6], tf->tf_reg[7]);
+ (*pr)(" r8=%016"PRIxREGISTER", r9=%016"PRIxREGISTER"\n",
+ tf->tf_reg[8], tf->tf_reg[9]);
+ (*pr)(" r10=%016"PRIxREGISTER", r11=%016"PRIxREGISTER"\n",
+ tf->tf_reg[10], tf->tf_reg[11]);
+ (*pr)(" r12=%016"PRIxREGISTER", sp=r13=%016"PRIxREGISTER"\n",
+ tf->tf_reg[12], tf->tf_reg[13]);
+ (*pr)("lr=r14=%016"PRIxREGISTER", pc=r15=%016"PRIxREGISTER"\n",
+ tf->tf_reg[14], tf->tf_pc);
+ return;
+ }
+#endif
(*pr)(" pc=%016"PRIxREGISTER", spsr=%016"PRIxREGISTER"\n",
tf->tf_pc, tf->tf_spsr);
(*pr)(" esr=%016"PRIxREGISTER", far=%016"PRIxREGISTER"\n",
@@ -388,6 +417,7 @@ db_md_sysreg_cmd(db_expr_t addr, bool ha
SHOW_ARMREG(spsr_el1);
SHOW_ARMREG(tcr_el1);
SHOW_ARMREG(tpidr_el0);
+ SHOW_ARMREG(tpidrro_el0);
SHOW_ARMREG(tpidr_el1);
SHOW_ARMREG(ttbr0_el1);
SHOW_ARMREG(ttbr1_el1);
Index: src/sys/arch/aarch64/aarch64/vectors.S
diff -u src/sys/arch/aarch64/aarch64/vectors.S:1.8 src/sys/arch/aarch64/aarch64/vectors.S:1.9
--- src/sys/arch/aarch64/aarch64/vectors.S:1.8 Fri Sep 14 05:33:50 2018
+++ src/sys/arch/aarch64/aarch64/vectors.S Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: vectors.S,v 1.8 2018/09/14 05:33:50 ryo Exp $ */
+/* $NetBSD: vectors.S,v 1.9 2018/10/12 01:28:57 ryo Exp $ */
#include <aarch64/asm.h>
#include "assym.h"
@@ -7,7 +7,7 @@
/*
* vector_entry macro must be small enough to fit 0x80 bytes!
*/
- .macro vector_entry, el, label
+ .macro vector_entry, el, label, tpidr
.align 7 /* aligned 0x80 */
.if \el == 1
@@ -61,11 +61,11 @@
.endif
.if \el == 0
- /* curlwp->l_private = tpidr_el0 */
+ /* curlwp->l_private = tpidr{,ro}_el0 */
mrs x1, tpidr_el1 /* curcpu() */
- ldr x1, [x1, #CI_CURLWP] /* x0 = curcpu()->ci_curlwp */
- mrs x0, tpidr_el0
- str x0, [x1, #L_PRIVATE] /* curlwp->l_private = tpidr_el0 */
+ ldr x1, [x1, #CI_CURLWP] /* x1 = curcpu()->ci_curlwp */
+ mrs x0, tpidr\tpidr\()_el0
+ str x0, [x1, #L_PRIVATE] /* curlwp->l_private = tpidr{,ro}_el0 */
.endif
adr x30, el\el\()_trap_exit /* el[01]_trap_exit */
@@ -110,8 +110,8 @@ ENTRY_NP(el1_vectors)
* Exception taken from lower Exception Level which is using AArch32
* There are entries for exceptions caused in EL0 (compat user exceptions).
*/
- vector_entry 0, trap_el0_32sync
- vector_entry 0, interrupt
- vector_entry 0, trap_el0_32fiq
- vector_entry 0, trap_el0_32error
+ vector_entry 0, trap_el0_32sync, ro
+ vector_entry 0, interrupt, ro
+ vector_entry 0, trap_el0_32fiq, ro
+ vector_entry 0, trap_el0_32error, ro
END(el1_vectors)
Index: src/sys/arch/aarch64/aarch64/exec_machdep.c
diff -u src/sys/arch/aarch64/aarch64/exec_machdep.c:1.2 src/sys/arch/aarch64/aarch64/exec_machdep.c:1.3
--- src/sys/arch/aarch64/aarch64/exec_machdep.c:1.2 Sun Apr 1 04:35:03 2018
+++ src/sys/arch/aarch64/aarch64/exec_machdep.c Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: exec_machdep.c,v 1.2 2018/04/01 04:35:03 ryo Exp $ */
+/* $NetBSD: exec_machdep.c,v 1.3 2018/10/12 01:28:57 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exec_machdep.c,v 1.2 2018/04/01 04:35:03 ryo Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_machdep.c,v 1.3 2018/10/12 01:28:57 ryo Exp $");
#include "opt_compat_netbsd.h"
#include "opt_compat_netbsd32.h"
@@ -62,19 +62,36 @@ aarch64_netbsd_elf64_probe(struct lwp *l
}
#endif
+#if EXEC_ELF32
+int
+aarch64_netbsd_elf32_probe(struct lwp *l, struct exec_package *epp, void *eh0,
+ char *itp, vaddr_t *start_p)
+{
+ const Elf32_Ehdr * const eh = eh0;
+ const bool elf_aapcs_p =
+ (eh->e_flags & EF_ARM_EABIMASK) >= EF_ARM_EABI_VER4;
+
+ /* OABI not support */
+ if (!elf_aapcs_p)
+ return ENOEXEC;
+
+ return 0;
+}
+#endif
+
void
setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
{
struct proc * const p = l->l_proc;
struct trapframe * const tf = l->l_md.md_utf;
- memset(tf, 0, sizeof(*tf));
+ p->p_flag &= ~PK_32;
/*
* void __start(void (*cleanup)(void), const Obj_Entry *obj,
* struct ps_strings *ps_strings);
*/
-
+ memset(tf, 0, sizeof(*tf));
tf->tf_reg[2] = p->p_psstrp;
tf->tf_pc = pack->ep_entry;
tf->tf_sp = stack & -16L;
Index: src/sys/arch/aarch64/aarch64/fault.c
diff -u src/sys/arch/aarch64/aarch64/fault.c:1.6 src/sys/arch/aarch64/aarch64/fault.c:1.7
--- src/sys/arch/aarch64/aarch64/fault.c:1.6 Sat Jul 21 13:23:48 2018
+++ src/sys/arch/aarch64/aarch64/fault.c Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: fault.c,v 1.6 2018/07/21 13:23:48 ryo Exp $ */
+/* $NetBSD: fault.c,v 1.7 2018/10/12 01:28:57 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -27,8 +27,9 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.6 2018/07/21 13:23:48 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fault.c,v 1.7 2018/10/12 01:28:57 ryo Exp $");
+#include "opt_compat_netbsd32.h"
#include "opt_ddb.h"
#include "opt_uvmhist.h"
@@ -118,6 +119,10 @@ is_fatal_abort(uint32_t esr)
return true;
}
+/* SPSR_M is SPSR_M_EL0T or SPSR_M_USR32 ? */
+#define IS_SPSR_USER(spsr) \
+ (((spsr) & (SPSR_M & ~SPSR_A32)) == 0)
+
void
data_abort_handler(struct trapframe *tf, uint32_t eclass)
{
@@ -129,8 +134,8 @@ data_abort_handler(struct trapframe *tf,
uint32_t esr, fsc, rw;
vm_prot_t ftype;
int error = 0, len;
- const bool user = (__SHIFTOUT(tf->tf_spsr, SPSR_M) == SPSR_M_EL0T) ?
- true : false;
+ const bool user = IS_SPSR_USER(tf->tf_spsr) ? true : false;
+
bool fatalabort;
const char *faultstr;
static char panicinfo[256];
Index: src/sys/arch/aarch64/aarch64/locore.S
diff -u src/sys/arch/aarch64/aarch64/locore.S:1.28 src/sys/arch/aarch64/aarch64/locore.S:1.29
--- src/sys/arch/aarch64/aarch64/locore.S:1.28 Thu Oct 4 23:53:13 2018
+++ src/sys/arch/aarch64/aarch64/locore.S Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.28 2018/10/04 23:53:13 ryo Exp $ */
+/* $NetBSD: locore.S,v 1.29 2018/10/12 01:28:57 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -27,6 +27,7 @@
*/
#include "opt_arm_debug.h"
+#include "opt_compat_netbsd32.h"
#include "opt_console.h"
#include "opt_cpuoptions.h"
#include "opt_ddb.h"
@@ -37,7 +38,7 @@
#include <aarch64/hypervisor.h>
#include "assym.h"
-RCSID("$NetBSD: locore.S,v 1.28 2018/10/04 23:53:13 ryo Exp $")
+RCSID("$NetBSD: locore.S,v 1.29 2018/10/12 01:28:57 ryo Exp $")
/*#define DEBUG_LOCORE /* debug print */
@@ -172,6 +173,7 @@ vstart:
/* lwp-private = NULL */
msr tpidr_el0, xzr
+ msr tpidrro_el0, xzr
/* set curcpu() */
ADDR x0, cpu_info_store /* cpu_info_store is cpu_info[0] */
@@ -426,6 +428,7 @@ mp_vstart:
/* lwp-private = NULL */
msr tpidr_el0, xzr
+ msr tpidrro_el0, xzr
/* set curcpu(), and fill curcpu()->ci_{midr,mpidr} */
mov x0, #CPU_INFO_SIZE
Index: src/sys/arch/aarch64/aarch64/pmap.c
diff -u src/sys/arch/aarch64/aarch64/pmap.c:1.28 src/sys/arch/aarch64/aarch64/pmap.c:1.29
--- src/sys/arch/aarch64/aarch64/pmap.c:1.28 Fri Oct 12 01:13:51 2018
+++ src/sys/arch/aarch64/aarch64/pmap.c Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.28 2018/10/12 01:13:51 ryo Exp $ */
+/* $NetBSD: pmap.c,v 1.29 2018/10/12 01:28:57 ryo Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.28 2018/10/12 01:13:51 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.29 2018/10/12 01:28:57 ryo Exp $");
#include "opt_arm_debug.h"
#include "opt_ddb.h"
@@ -735,6 +735,47 @@ _pmap_pte_lookup_l3(struct pmap *pm, vad
return NULL;
}
+void
+pmap_icache_sync_range(pmap_t pm, vaddr_t sva, vaddr_t eva)
+{
+ pt_entry_t *ptep, pte;
+ vaddr_t va;
+ vsize_t blocksize = 0;
+
+ pm_lock(pm);
+
+ for (va = sva; va < eva; va += blocksize) {
+ ptep = _pmap_pte_lookup_bs(pm, va, &blocksize);
+ if (blocksize == 0)
+ break;
+ if (ptep != NULL) {
+ vaddr_t eob = (va + blocksize) & ~(blocksize - 1);
+ vsize_t len = ulmin(eva, eob - va);
+
+ pte = *ptep;
+ if (l3pte_writable(pte)) {
+ cpu_icache_sync_range(va, len);
+ } else {
+ /*
+ * change to writable temporally
+ * to do cpu_icache_sync_range()
+ */
+ pt_entry_t opte = pte;
+ pte = pte & ~(LX_BLKPAG_AF|LX_BLKPAG_AP);
+ pte |= (LX_BLKPAG_AF|LX_BLKPAG_AP_RW);
+ atomic_swap_64(ptep, pte);
+ AARCH64_TLBI_BY_ASID_VA(pm->pm_asid, va, true);
+ cpu_icache_sync_range(va, len);
+ atomic_swap_64(ptep, opte);
+ AARCH64_TLBI_BY_ASID_VA(pm->pm_asid, va, true);
+ }
+ va &= ~(blocksize - 1);
+ }
+ }
+
+ pm_unlock(pm);
+}
+
static pt_entry_t
_pmap_pte_adjust_prot(pt_entry_t pte, vm_prot_t prot, vm_prot_t protmask,
bool user)
Index: src/sys/arch/aarch64/aarch64/netbsd32_machdep.c
diff -u src/sys/arch/aarch64/aarch64/netbsd32_machdep.c:1.1 src/sys/arch/aarch64/aarch64/netbsd32_machdep.c:1.2
--- src/sys/arch/aarch64/aarch64/netbsd32_machdep.c:1.1 Sun Apr 1 04:35:03 2018
+++ src/sys/arch/aarch64/aarch64/netbsd32_machdep.c Fri Oct 12 01:28:57 2018
@@ -1,10 +1,9 @@
-/*-
- * Copyright (c) 2018 The NetBSD Foundation, Inc.
+/* $NetBSD: netbsd32_machdep.c,v 1.2 2018/10/12 01:28:57 ryo Exp $ */
+
+/*
+ * Copyright (c) 2018 Ryo Shimizu <[email protected]>
* All rights reserved.
*
- * This code is derived from software contributed to The NetBSD Foundation
- * by Nick Hudson
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -14,22 +13,21 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``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 FOUNDATION OR CONTRIBUTORS
- * 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
+ * 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 <sys/cdefs.h>
-
-__KERNEL_RCSID(1, "$NetBSD: netbsd32_machdep.c,v 1.1 2018/04/01 04:35:03 ryo Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.2 2018/10/12 01:28:57 ryo Exp $");
#include "opt_compat_netbsd.h"
@@ -37,6 +35,7 @@ __KERNEL_RCSID(1, "$NetBSD: netbsd32_mac
#include <sys/core.h>
#include <sys/exec.h>
#include <sys/lwp.h>
+#include <sys/ras.h>
#include <sys/signalvar.h>
#include <sys/syscallargs.h>
@@ -46,69 +45,486 @@ __KERNEL_RCSID(1, "$NetBSD: netbsd32_mac
#include <compat/netbsd32/netbsd32_exec.h>
#include <compat/netbsd32/netbsd32_syscallargs.h>
-#include <machine/frame.h>
+#include <aarch64/armreg.h>
+#include <aarch64/cpufunc.h>
+#include <aarch64/frame.h>
+#include <aarch64/machdep.h>
+#include <aarch64/userret.h>
const char machine32[] = MACHINE;
-const char machine_arch32[] = MACHINE_ARCH;
+#ifdef __AARCH64EB__
+const char machine_arch32[] = "earmv7hfeb";
+#else
+const char machine_arch32[] = "earmv7hf";
+#endif
void
netbsd32_setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
{
+ struct proc * const p = l->l_proc;
+ struct trapframe * const tf = l->l_md.md_utf;
+
+ p->p_flag |= PK_32;
+
+ /*
+ * void __start(struct ps_strings *ps_strings, const Obj_Entry *obj,
+ * void (*cleanup)(void));
+ */
+ memset(tf, 0, sizeof(*tf));
+ tf->tf_reg[0] = (uint32_t)p->p_psstrp;
+ tf->tf_reg[12] = stack; /* r12 needed by pre 1.4 crt0.c */
+ tf->tf_reg[13] = stack; /* sp */
+ tf->tf_reg[14] = pack->ep_entry;/* lr */
+ tf->tf_reg[18] = 0x77777777; /* svc_lr. adjust to arm_machdep.c */
+ tf->tf_pc = pack->ep_entry;
+
+
+ /* set 32bit mode, and same endian as 64bit's */
+#ifdef __AARCH64EB__
+ tf->tf_spsr = SPSR_M_USR32 | SPSR_A32_E;
+#else
+ tf->tf_spsr = SPSR_M_USR32;
+#endif
+
+#ifdef THUMB_CODE
+ if (pack->ep_entry & 1)
+ tf->tf_spsr |= SPSR_A32_T;
+#endif
+}
+
+/* aarch32 fpscr register is assigned to two registers fpsr/fpcr on aarch64 */
+#define FPSR_BITS \
+ (FPSR_N32|FPSR_Z32|FPSR_C32|FPSR_V32|FPSR_QC| \
+ FPSR_IDC|FPSR_IXC|FPSR_UFC|FPSR_OFC|FPSR_DZC|FPSR_IOC)
+#define FPCR_BITS \
+ (FPCR_AHP|FPCR_DN|FPCR_FZ|FPCR_RMODE|FPCR_STRIDE|FPCR_LEN| \
+ FPCR_IDE|FPCR_IXE|FPCR_UFE|FPCR_OFE|FPCR_DZE|FPCR_IOE)
+
+static int
+netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs)
+{
+ struct proc * const p = l->l_proc;
+ struct trapframe *tf = l->l_md.md_utf;
+ int i;
+
+ if ((p->p_flag & PK_32) == 0)
+ return EINVAL;
+
+ for (i = 0; i < 13; i++)
+ regs->r[i] = tf->tf_reg[i]; /* r0-r12 */
+ regs->r_sp = tf->tf_reg[13]; /* r13 = sp */
+ regs->r_lr = tf->tf_reg[14]; /* r14 = lr */
+ regs->r_pc = tf->tf_pc; /* r15 = pc */
+ regs->r_cpsr = tf->tf_spsr;
+
+ return 0;
}
+static int
+netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *fpregs,
+ size_t *lenp)
+{
+ struct proc * const p = l->l_proc;
+ struct pcb * const pcb = lwp_getpcb(l);
+ int i;
+
+ if ((p->p_flag & PK_32) == 0)
+ return EINVAL;
+
+ KASSERT(*lenp <= sizeof(*fpregs));
+ fpu_save(l);
+
+ /*
+ * convert from aarch64's struct fpreg to arm's struct fpreg32
+ */
+#define VFP_FPEXC_EN 0x40000000 /* VFP Enable bit */
+#define VFP_FPEXC_VECITR 0x00000700 /* VECtor ITeRation count */
+ fpregs->fpr_vfp.vfp_fpexc = VFP_FPEXC_EN | VFP_FPEXC_VECITR;
+
+ fpregs->fpr_vfp.vfp_fpscr =
+ (pcb->pcb_fpregs.fpsr & FPSR_BITS) |
+ (pcb->pcb_fpregs.fpcr & FPCR_BITS);
+
+ fpregs->fpr_vfp.vfp_fpinst = 0;
+ fpregs->fpr_vfp.vfp_fpinst2 = 0;
+
+ for (i = 0; i < 32; i++) {
+#ifdef __AARCH64EB__
+ fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[1];
+#else
+ fpregs->fpr_vfp.vfp_regs[i] = pcb->pcb_fpregs.fp_reg[i].u64[0];
+#endif
+ }
+
+ return 0;
+}
int
cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie,
struct core32 *chdr)
{
+ struct netbsd32_cpustate md_core32;
+ struct coreseg32 cseg;
+ int error;
+
+ if (iocookie == NULL) {
+ CORE_SETMAGIC(*chdr, COREMAGIC, MID_ARM6, 0);
+ chdr->c_hdrsize = ALIGN32(sizeof(*chdr));
+ chdr->c_seghdrsize = ALIGN32(sizeof(cseg));
+ chdr->c_cpusize = sizeof(md_core32);
+ chdr->c_nseg++;
+ return 0;
+ }
+
+ error = netbsd32_process_read_regs(l, &md_core32.regs);
+ if (error)
+ return error;
+
+ error = netbsd32_process_read_fpregs(l, &md_core32.fpregs, NULL);
+ if (error)
+ return error;
+
+ CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_ARM6, CORE_CPU);
+ cseg.c_addr = 0;
+ cseg.c_size = chdr->c_cpusize;
+
+ error = coredump_write(iocookie, UIO_SYSSPACE,
+ &cseg, chdr->c_seghdrsize);
+ if (error)
+ return error;
- return ENOSYS;
+ return coredump_write(iocookie, UIO_SYSSPACE,
+ &md_core32, sizeof(md_core32));
}
+static void
+netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
+{
+ struct lwp * const l = curlwp;
+ struct proc * const p = l->l_proc;
+ struct trapframe * const tf = l->l_md.md_utf;
+ struct sigaltstack * const ss = &l->l_sigstk;
+ const int signo = ksi->ksi_signo;
+ const struct sigaction * const sa = &SIGACTION(p, signo);
+ const struct sigact_sigdesc * const sdesc =
+ &p->p_sigacts->sa_sigdesc[signo];
+ const sig_t handler = sa->sa_handler;
+ struct netbsd32_sigframe_siginfo *fp, frame;
+ int error;
+
+ const bool onstack_p =
+ (ss->ss_flags & (SS_DISABLE | SS_ONSTACK)) &&
+ (sa->sa_flags & SA_ONSTACK);
+
+ vaddr_t sp = onstack_p ?
+ ((vaddr_t)ss->ss_sp + ss->ss_size) :
+ tf->tf_reg[13]; /* r13 = sp on aarch32 */
+
+ fp = (struct netbsd32_sigframe_siginfo *)sp;
+ fp = (struct netbsd32_sigframe_siginfo *)STACK_ALIGN(fp - 1, 8);
+
+ /* XXX: netbsd32_ksi_to_si32 */
+ netbsd32_si_to_si32(&frame.sf_si, (const siginfo_t *)&ksi->ksi_info);
+
+ frame.sf_uc.uc_flags = _UC_SIGMASK;
+ frame.sf_uc.uc_sigmask = *mask;
+ frame.sf_uc.uc_link = (uint32_t)(uintptr_t)l->l_ctxlink;
+ frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK) ?
+ _UC_SETSTACK : _UC_CLRSTACK;
+ memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack));
+ sendsig_reset(l, signo);
+
+ mutex_exit(p->p_lock);
+ cpu_getmcontext32(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
+ error = copyout(&frame, fp, sizeof(frame));
+ mutex_enter(p->p_lock);
+
+ if (error != 0) {
+ /*
+ * Process has trashed its stack;
+ * give it an illegal instruction to halt it in its tracks.
+ */
+ sigexit(l, SIGILL);
+ /* NOTREACHED */
+ }
+
+ tf->tf_reg[0] = signo;
+ tf->tf_reg[1] = (uint32_t)(uintptr_t)&fp->sf_si;
+ tf->tf_reg[2] = (uint32_t)(uintptr_t)&fp->sf_uc;
+
+ /* the trampoline uses r5 as the uc address */
+ tf->tf_reg[5] = (uint32_t)(uintptr_t)&fp->sf_uc;
+ tf->tf_pc = (uint32_t)(uintptr_t)handler;
+#ifdef THUMB_CODE
+ if (((int)handler) & 1)
+ tf->tf_spsr |= SPSR_A32_T;
+ else
+ tf->tf_spsr &= ~SPSR_A32_T;
+#endif
+ tf->tf_reg[13] = (uint32_t)(uintptr_t)fp; /* sp */
+ tf->tf_reg[14] = (uint32_t)(uintptr_t)sdesc->sd_tramp; /* lr */
+
+ /* Remember if we'ere now on the signal stack */
+ if (onstack_p)
+ ss->ss_flags |= SS_ONSTACK;
+}
void
-netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *ss)
+netbsd32_sendsig(const ksiginfo_t *ksi, const sigset_t *mask)
{
-
+#ifdef COMPAT_16
+#error non EABI generation binaries are not supported
+ if (curproc->p_sigacts->sa_sigdesc[ksi->ksi_signo].sd_vers < 2)
+ netbsd32_sendsig_sigcontext(ksi, mask);
+ else
+#endif
+ netbsd32_sendsig_siginfo(ksi, mask);
}
void
startlwp32(void *arg)
{
-
+ ucontext32_t *uc = arg;
+ lwp_t *l = curlwp;
+ int error __diagused;
+
+ /*
+ * entity of *uc is ucontext_t. therefore
+ * ucontext_t must be greater than ucontext32_t
+ */
+ CTASSERT(sizeof(ucontext_t) >= sizeof(ucontext32_t));
+
+ error = cpu_setmcontext32(l, &uc->uc_mcontext, uc->uc_flags);
+ KASSERT(error == 0);
+
+ /* Note: we are freeing ucontext_t, not ucontext32_t. */
+ kmem_free(uc, sizeof(ucontext_t));
+ userret(l);
}
int
cpu_mcontext32_validate(struct lwp *l, const mcontext32_t *mcp)
{
+ struct proc * const p = l->l_proc;
+ const uint32_t spsr = mcp->__gregs[_REG_CPSR];
-// const __greg32_t * const gr = mcp->__gregs;
+ KASSERT(p->p_flag & PK_32);
-// /* Make sure the processor mode has not been tampered with. */
-// if (!VALID_R15_PSR(gr[_REG_PC], gr[_REG_CPSR]))
-// return EINVAL;
+ if (__SHIFTOUT(spsr, SPSR_M) != SPSR_M_USR32)
+ return EINVAL;
+ if ((spsr & (SPSR_A64_D|SPSR_A|SPSR_I|SPSR_F)) != 0)
+ return EINVAL;
+
+#ifdef __AARCH64EB__
+ if ((spsr & SPSR_A32_E) == 0)
+ return EINVAL;
+#else
+ if ((spsr & SPSR_A32_E) != 0)
+ return EINVAL;
+#endif
+
+ if ((spsr & (SPSR_A|SPSR_I|SPSR_F)) != 0)
+ return EINVAL;
return 0;
}
void
cpu_getmcontext32(struct lwp *l, mcontext32_t *mcp, unsigned int *flagsp)
{
+ struct trapframe * const tf = l->l_md.md_utf;
+ __greg32_t *gr = mcp->__gregs;
+ __greg32_t ras_pc;
+
+ gr[_REG_R0] = tf->tf_reg[0];
+ gr[_REG_R1] = tf->tf_reg[1];
+ gr[_REG_R2] = tf->tf_reg[2];
+ gr[_REG_R3] = tf->tf_reg[3];
+ gr[_REG_R4] = tf->tf_reg[4];
+ gr[_REG_R5] = tf->tf_reg[5];
+ gr[_REG_R6] = tf->tf_reg[6];
+ gr[_REG_R7] = tf->tf_reg[7];
+ gr[_REG_R8] = tf->tf_reg[8];
+ gr[_REG_R9] = tf->tf_reg[9];
+ gr[_REG_R10] = tf->tf_reg[10];
+ gr[_REG_R11] = tf->tf_reg[11];
+ gr[_REG_R12] = tf->tf_reg[12];
+ gr[_REG_R13] = tf->tf_reg[13];
+ gr[_REG_R14] = tf->tf_reg[14];
+ gr[_REG_R15] = tf->tf_pc;
+ gr[_REG_CPSR] = tf->tf_spsr;
+
+ if ((ras_pc = (__greg32_t)(uintptr_t)ras_lookup(l->l_proc,
+ (void *)(uintptr_t)gr[_REG_R15])) != -1) {
+ gr[_REG_R15] = ras_pc;
+ }
+ *flagsp |= _UC_CPU;
+
+ /* fpu context */
+ if (fpu_used_p(l)) {
+ const struct pcb * const pcb = lwp_getpcb(l);
+ int i;
+
+ fpu_save(l);
+
+ CTASSERT(__arraycount(mcp->__vfpregs.__vfp_fstmx) ==
+ __arraycount(pcb->pcb_fpregs.fp_reg));
+ for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) {
+ mcp->__vfpregs.__vfp_fstmx[i] =
+#ifdef __AARCH64EB__
+ pcb->pcb_fpregs.fp_reg[i].u64[1];
+#else
+ pcb->pcb_fpregs.fp_reg[i].u64[0];
+#endif
+ }
+
+ mcp->__vfpregs.__vfp_fpscr =
+ (pcb->pcb_fpregs.fpsr & FPSR_BITS) |
+ (pcb->pcb_fpregs.fpcr & FPCR_BITS);
+ mcp->__vfpregs.__vfp_fpsid = 0; /* XXX: build FPSID from MIDR */
+
+ *flagsp |= _UC_FPU;
+ }
+ mcp->_mc_tlsbase = (uint32_t)(uintptr_t)l->l_private;
+ *flagsp |= _UC_TLSBASE;
}
int
cpu_setmcontext32(struct lwp *l, const mcontext32_t *mcp, unsigned int flags)
{
+ struct trapframe * const tf = l->l_md.md_utf;
+ const __greg32_t * const gr = mcp->__gregs;
+ struct proc * const p = l->l_proc;
+ int error, i;
+
+ if (flags & _UC_CPU) {
+ error = cpu_mcontext32_validate(l, mcp);
+ if (error != 0)
+ return error;
+
+ tf->tf_reg[0] = gr[_REG_R0];
+ tf->tf_reg[1] = gr[_REG_R1];
+ tf->tf_reg[2] = gr[_REG_R2];
+ tf->tf_reg[3] = gr[_REG_R3];
+ tf->tf_reg[4] = gr[_REG_R4];
+ tf->tf_reg[5] = gr[_REG_R5];
+ tf->tf_reg[6] = gr[_REG_R6];
+ tf->tf_reg[7] = gr[_REG_R7];
+ tf->tf_reg[8] = gr[_REG_R8];
+ tf->tf_reg[9] = gr[_REG_R9];
+ tf->tf_reg[10] = gr[_REG_R10];
+ tf->tf_reg[11] = gr[_REG_R11];
+ tf->tf_reg[12] = gr[_REG_R12];
+ tf->tf_reg[13] = gr[_REG_R13];
+ tf->tf_reg[14] = gr[_REG_R14];
+ tf->tf_pc = gr[_REG_R15];
+ tf->tf_spsr = gr[_REG_CPSR];
+ }
+
+ if (flags & _UC_FPU) {
+ struct pcb * const pcb = lwp_getpcb(l);
+ fpu_discard(l, true);
+
+ CTASSERT(__arraycount(mcp->__vfpregs.__vfp_fstmx) ==
+ __arraycount(pcb->pcb_fpregs.fp_reg));
+ for (i = 0; i < __arraycount(pcb->pcb_fpregs.fp_reg); i++) {
+#ifdef __AARCH64EB__
+ pcb->pcb_fpregs.fp_reg[i].u64[0] = 0;
+ pcb->pcb_fpregs.fp_reg[i].u64[1] =
+#else
+ pcb->pcb_fpregs.fp_reg[i].u64[1] = 0;
+ pcb->pcb_fpregs.fp_reg[i].u64[0] =
+#endif
+ mcp->__vfpregs.__vfp_fstmx[i];
+ }
+ pcb->pcb_fpregs.fpsr =
+ mcp->__vfpregs.__vfp_fpscr & FPSR_BITS;
+ pcb->pcb_fpregs.fpcr =
+ mcp->__vfpregs.__vfp_fpscr & FPCR_BITS;
+ }
+
+ if (flags &_UC_TLSBASE)
+ l->l_private = (void *)(uintptr_t)mcp->_mc_tlsbase;
+
+ mutex_enter(p->p_lock);
+ if (flags & _UC_SETSTACK)
+ l->l_sigstk.ss_flags |= SS_ONSTACK;
+ if (flags & _UC_CLRSTACK)
+ l->l_sigstk.ss_flags &= ~SS_ONSTACK;
+ mutex_exit(p->p_lock);
- return EINVAL;
+ return 0;
+}
+
+static int
+arm32_sync_icache(struct lwp *l, const void *args, register_t *retval)
+{
+ struct netbsd32_arm_sync_icache_args ua;
+ struct faultbuf fb;
+ int error;
+
+ error = copyin(args, &ua, sizeof(ua));
+ if (error != 0)
+ return error;
+
+ if ((vaddr_t)ua.addr + ua.len > VM_MAXUSER_ADDRESS32)
+ return EINVAL;
+
+ /* use cpu_set_onfault() by way of precaution */
+ if ((error = cpu_set_onfault(&fb)) == 0) {
+ pmap_icache_sync_range(
+ vm_map_pmap(&l->l_proc->p_vmspace->vm_map),
+ (vaddr_t)ua.addr, (vaddr_t)ua.addr + ua.len);
+ cpu_unset_onfault();
+ }
+
+ *retval = 0;
+ return error;
+}
+
+static int
+arm32_drain_writebuf(struct lwp *l, const void *args, register_t *retval)
+{
+ aarch64_drain_writebuf();
+
+ *retval = 0;
+ return 0;
}
int
netbsd32_sysarch(struct lwp *l, const struct netbsd32_sysarch_args *uap,
- register_t *retval)
+ register_t *retval)
{
-
- return EINVAL;
+ /* {
+ syscallarg(int) op;
+ syscallarg(netbsd32_voidp) parms;
+ } */
+ int error;
+
+ switch (SCARG(uap, op)) {
+ case ARM_SYNC_ICACHE:
+ error = arm32_sync_icache(l,
+ NETBSD32PTR64(SCARG(uap, parms)), retval);
+ break;
+ case ARM_DRAIN_WRITEBUF:
+ error = arm32_drain_writebuf(l,
+ NETBSD32PTR64(SCARG(uap, parms)), retval);
+ break;
+ case ARM_VFP_FPSCR:
+ printf("%s: ARM_VFP_FPSCR not implemented\n", __func__);
+ error = EINVAL;
+ break;
+ case ARM_FPU_USED:
+ printf("%s: ARM_FPU_USED not implemented\n", __func__);
+ error = EINVAL;
+ break;
+ default:
+ printf("%s: op=%d: not implemented\n", __func__,
+ SCARG(uap, op));
+ error = EINVAL;
+ break;
+ }
+ return error;
}
vaddr_t
@@ -116,8 +532,7 @@ netbsd32_vm_default_addr(struct proc *p,
int topdown)
{
if (topdown)
- return VM_DEFAULT_ADDRESS_TOPDOWN(base, sz);
+ return VM_DEFAULT_ADDRESS32_TOPDOWN(base, sz);
else
- return VM_DEFAULT_ADDRESS_BOTTOMUP(base, sz);
+ return VM_DEFAULT_ADDRESS32_BOTTOMUP(base, sz);
}
-
Index: src/sys/arch/aarch64/aarch64/trap.c
diff -u src/sys/arch/aarch64/aarch64/trap.c:1.10 src/sys/arch/aarch64/aarch64/trap.c:1.11
--- src/sys/arch/aarch64/aarch64/trap.c:1.10 Fri Sep 14 13:47:14 2018
+++ src/sys/arch/aarch64/aarch64/trap.c Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.10 2018/09/14 13:47:14 ryo Exp $ */
+/* $NetBSD: trap.c,v 1.11 2018/10/12 01:28:57 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.10 2018/09/14 13:47:14 ryo Exp $");
+__KERNEL_RCSID(1, "$NetBSD: trap.c,v 1.11 2018/10/12 01:28:57 ryo Exp $");
#include "opt_arm_intr_impl.h"
#include "opt_compat_netbsd32.h"
@@ -267,21 +267,21 @@ trap_el0_sync(struct trapframe *tf)
case ESR_EC_BRKPNT_EL0:
case ESR_EC_SW_STEP_EL0:
case ESR_EC_WTCHPNT_EL0:
- /* XXX notyet */
do_trapsignal(l, SIGTRAP, TRAP_BRKPT, (void *)tf->tf_pc, esr);
userret(l);
break;
default:
- /* XXX notyet */
case ESR_EC_UNKNOWN:
#ifdef DDB
if (sigill_debug) {
/* show illegal instruction */
- printf("TRAP: pid %d (%s), uid %d: %s: pc=0x%016lx: %s\n",
+ printf("TRAP: pid %d (%s), uid %d: %s:"
+ " esr=0x%lx: pc=0x%lx: %s\n",
curlwp->l_proc->p_pid, curlwp->l_proc->p_comm,
l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1,
- eclass_trapname(eclass), tf->tf_pc, strdisasm(tf->tf_pc));
+ eclass_trapname(eclass), tf->tf_esr, tf->tf_pc,
+ strdisasm(tf->tf_pc));
}
#endif
/* illegal or not implemented instruction */
@@ -317,48 +317,58 @@ trap_el0_32sync(struct trapframe *tf)
daif_enable(DAIF_D|DAIF_A|DAIF_I|DAIF_F);
switch (eclass) {
- case ESR_EC_FP_ACCESS:
- fpu_load(l);
- userret(l);
- break;
-
+#ifdef COMPAT_NETBSD32
case ESR_EC_INSN_ABT_EL0:
case ESR_EC_DATA_ABT_EL0:
data_abort_handler(tf, eclass);
userret(l);
break;
+ case ESR_EC_SVC_A32:
+ (*l->l_proc->p_md.md_syscall)(tf);
+ break;
+ case ESR_EC_FP_ACCESS:
+ fpu_load(l);
+ userret(l);
+ break;
+ case ESR_EC_FP_TRAP_A32:
+ do_trapsignal(l, SIGFPE, FPE_FLTUND, NULL, esr); /* XXX */
+ userret(l);
+
case ESR_EC_PC_ALIGNMENT:
do_trapsignal(l, SIGBUS, BUS_ADRALN, (void *)tf->tf_pc, esr);
userret(l);
break;
case ESR_EC_SP_ALIGNMENT:
- do_trapsignal(l, SIGBUS, BUS_ADRALN, (void *)tf->tf_sp, esr);
+ do_trapsignal(l, SIGBUS, BUS_ADRALN,
+ (void *)tf->tf_reg[13], esr); /* sp is r13 on AArch32 */
userret(l);
break;
-#ifdef COMPAT_NETBSD32
- case ESR_EC_SVC_A32:
- (*l->l_proc->p_md.md_syscall)(tf);
+ case ESR_EC_BKPT_INSN_A32:
+ do_trapsignal(l, SIGTRAP, TRAP_BRKPT, (void *)tf->tf_pc, esr);
+ userret(l);
break;
+
case ESR_EC_CP15_RT:
case ESR_EC_CP15_RRT:
case ESR_EC_CP14_RT:
case ESR_EC_CP14_DT:
case ESR_EC_CP14_RRT:
- case ESR_EC_FP_TRAP_A32:
- case ESR_EC_BKPT_INSN_A32:
- /* XXX notyet */
- printf("%s:%d: %s\n", __func__, __LINE__,
- eclass_trapname(eclass));
- do_trapsignal(l, SIGILL, ILL_ILLTRP, (void *)tf->tf_pc, esr);
- userret(l);
- break;
#endif /* COMPAT_NETBSD32 */
default:
- /* XXX notyet */
- printf("%s:%d: %s\n", __func__, __LINE__,
- eclass_trapname(eclass));
+#ifdef DDB
+ if (sigill_debug) {
+ /* show illegal instruction */
+ printf("TRAP: pid %d (%s), uid %d: %s:"
+ " esr=0x%lx: pc=0x%lx: %s\n",
+ curlwp->l_proc->p_pid, curlwp->l_proc->p_comm,
+ l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1,
+ eclass_trapname(eclass), tf->tf_esr, tf->tf_pc,
+ strdisasm_aarch32(tf->tf_pc));
+ }
+#endif
+ /* illegal or not implemented instruction */
do_trapsignal(l, SIGILL, ILL_ILLTRP, (void *)tf->tf_pc, esr);
userret(l);
break;
Index: src/sys/arch/aarch64/conf/files.aarch64
diff -u src/sys/arch/aarch64/conf/files.aarch64:1.6 src/sys/arch/aarch64/conf/files.aarch64:1.7
--- src/sys/arch/aarch64/conf/files.aarch64:1.6 Sat Oct 6 17:46:46 2018
+++ src/sys/arch/aarch64/conf/files.aarch64 Fri Oct 12 01:28:57 2018
@@ -1,4 +1,4 @@
-# $NetBSD: files.aarch64,v 1.6 2018/10/06 17:46:46 skrll Exp $
+# $NetBSD: files.aarch64,v 1.7 2018/10/12 01:28:57 ryo Exp $
defflag opt_cpuoptions.h AARCH64_ALIGNMENT_CHECK
defflag opt_cpuoptions.h AARCH64_EL0_STACK_ALIGNMENT_CHECK
@@ -117,8 +117,7 @@ file arch/aarch64/aarch64/pmap_page.S
# NetBSD 32-bit binary compatibility
include "compat/netbsd32/files.netbsd32"
file arch/aarch64/aarch64/netbsd32_machdep.c compat_netbsd32
-#file arch/aarch64/aarch32/aarch32_oabi_machdep.c compat_aarch32_oabi
-#file arch/aarch64/aarch32/aarch32_eabi_machdep.c compat_aarch32_eabi
+file arch/aarch64/aarch64/netbsd32_syscall.c compat_netbsd32
#file arch/aarch64/aarch32/compat_13_machdep.c compat_13 & compat_netbsd32
#file arch/aarch64/aarch32/compat_16_machdep.c compat_16 & compat_netbsd32
Index: src/sys/arch/aarch64/include/armreg.h
diff -u src/sys/arch/aarch64/include/armreg.h:1.18 src/sys/arch/aarch64/include/armreg.h:1.19
--- src/sys/arch/aarch64/include/armreg.h:1.18 Sun Aug 12 17:21:35 2018
+++ src/sys/arch/aarch64/include/armreg.h Fri Oct 12 01:28:58 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: armreg.h,v 1.18 2018/08/12 17:21:35 skrll Exp $ */
+/* $NetBSD: armreg.h,v 1.19 2018/10/12 01:28:58 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -599,6 +599,7 @@ AARCH64REG_WRITE_INLINE(spsr_el1)
#define SPSR_I __BIT(7) // IRQ Mask
#define SPSR_F __BIT(6) // FIQ Mask
#define SPSR_A32_T __BIT(5) // A32 Thumb Mode
+#define SPSR_A32 __BIT(4) // A32 Mode (a part of SPSR_M)
#define SPSR_M __BITS(4,0) // Execution State
#define SPSR_M_EL3H 0x0d
#define SPSR_M_EL3T 0x0c
Index: src/sys/arch/aarch64/include/db_machdep.h
diff -u src/sys/arch/aarch64/include/db_machdep.h:1.7 src/sys/arch/aarch64/include/db_machdep.h:1.8
--- src/sys/arch/aarch64/include/db_machdep.h:1.7 Sat Sep 15 19:47:48 2018
+++ src/sys/arch/aarch64/include/db_machdep.h Fri Oct 12 01:28:58 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: db_machdep.h,v 1.7 2018/09/15 19:47:48 jakllsch Exp $ */
+/* $NetBSD: db_machdep.h,v 1.8 2018/10/12 01:28:58 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -203,6 +203,7 @@ db_addr_t db_branch_taken(db_expr_t, db_
#define DB_MACHINE_COMMANDS
void dump_trapframe(struct trapframe *, void (*)(const char *, ...));
const char *strdisasm(vaddr_t);
+const char *strdisasm_aarch32(vaddr_t);
void db_machdep_init(void);
/* hardware breakpoint/watchpoint functions */
Index: src/sys/arch/aarch64/include/elf_machdep.h
diff -u src/sys/arch/aarch64/include/elf_machdep.h:1.3 src/sys/arch/aarch64/include/elf_machdep.h:1.4
--- src/sys/arch/aarch64/include/elf_machdep.h:1.3 Wed Aug 15 11:08:18 2018
+++ src/sys/arch/aarch64/include/elf_machdep.h Fri Oct 12 01:28:58 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: elf_machdep.h,v 1.3 2018/08/15 11:08:18 ryo Exp $ */
+/* $NetBSD: elf_machdep.h,v 1.4 2018/10/12 01:28:58 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -64,8 +64,8 @@
#define EF_ARM_EABI_VER4 0x04000000
#define EF_ARM_EABI_VER5 0x05000000
-#define ELF32_MACHDEP_ID_CASES \
- case EM_AARCH64: \
+#define ELF32_MACHDEP_ID_CASES \
+ case EM_ARM: \
break;
#define ELF64_MACHDEP_ID_CASES \
@@ -73,6 +73,7 @@
break;
#define ELF64_MACHDEP_ID EM_AARCH64
+#define ELF32_MACHDEP_ID EM_ARM
#define KERN_ELFSIZE 64
#define ARCH_ELFSIZE 64 /* MD native binary size */
@@ -242,6 +243,8 @@ struct exec_package;
int aarch64_netbsd_elf64_probe(struct lwp *, struct exec_package *, void *,
char *, vaddr_t *);
+int aarch64_netbsd_elf32_probe(struct lwp *, struct exec_package *, void *,
+ char *, vaddr_t *);
#endif
#elif defined(__arm__)
Index: src/sys/arch/aarch64/include/param.h
diff -u src/sys/arch/aarch64/include/param.h:1.3 src/sys/arch/aarch64/include/param.h:1.4
--- src/sys/arch/aarch64/include/param.h:1.3 Sat Apr 28 10:53:02 2018
+++ src/sys/arch/aarch64/include/param.h Fri Oct 12 01:28:58 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: param.h,v 1.3 2018/04/28 10:53:02 jmcneill Exp $ */
+/* $NetBSD: param.h,v 1.4 2018/10/12 01:28:58 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -80,7 +80,10 @@
/* AARCH64-specific macro to align a stack pointer (downwards). */
#define STACK_ALIGNBYTES (16 - 1)
-#define ALIGNBYTES32 7
+
+#define ALIGNBYTES32 (4 - 1)
+#define ALIGN32(p) \
+ (((uintptr_t)(p) + ALIGNBYTES32) & ~ALIGNBYTES32)
#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
#define DEV_BSIZE (1 << DEV_BSHIFT)
Index: src/sys/arch/aarch64/include/netbsd32_machdep.h
diff -u src/sys/arch/aarch64/include/netbsd32_machdep.h:1.1 src/sys/arch/aarch64/include/netbsd32_machdep.h:1.2
--- src/sys/arch/aarch64/include/netbsd32_machdep.h:1.1 Sun Apr 1 04:35:03 2018
+++ src/sys/arch/aarch64/include/netbsd32_machdep.h Fri Oct 12 01:28:58 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_machdep.h,v 1.1 2018/04/01 04:35:03 ryo Exp $ */
+/* $NetBSD: netbsd32_machdep.h,v 1.2 2018/10/12 01:28:58 ryo Exp $ */
#ifndef _MACHINE_NETBSD32_H_
#define _MACHINE_NETBSD32_H_
@@ -15,8 +15,6 @@ typedef struct { NETBSD32_POINTER_TYPE i
typedef netbsd32_pointer_t netbsd32_sigcontextp_t;
-#define netbsd32_syscall_intern syscall_intern
-
struct netbsd32_sigcontext13 {
int32_t sc_onstack; /* sigstack state to restore */
int32_t __sc_mask13; /* signal mask to restore (old style) */
@@ -67,6 +65,46 @@ struct netbsd32_sigcontext {
sigset_t sc_mask; /* signal mask to restore (new style) */
};
-#define NETBSD32_MID_MACHINE MID_ARM
+struct netbsd32_sigframe_siginfo {
+ siginfo32_t sf_si;
+ ucontext32_t sf_uc;
+};
+
+struct reg32 {
+ uint32_t r[13];
+ uint32_t r_sp;
+ uint32_t r_lr;
+ uint32_t r_pc;
+ uint32_t r_cpsr;
+};
+
+struct vfpreg32 {
+ uint32_t vfp_fpexc;
+ uint32_t vfp_fpscr;
+ uint32_t vfp_fpinst;
+ uint32_t vfp_fpinst2;
+ uint64_t vfp_regs[33]; /* In case we need fstmx format. */
+};
+
+struct fpreg32 {
+ struct vfpreg32 fpr_vfp;
+};
+
+/* same as cpustate in arm/arm/core_machdep.c */
+struct netbsd32_cpustate {
+ struct reg32 regs;
+ struct fpreg32 fpregs;
+};
+
+/* compat netbsd/arm sysarch(2) */
+#define ARM_SYNC_ICACHE 0
+#define ARM_DRAIN_WRITEBUF 1
+#define ARM_VFP_FPSCR 2
+#define ARM_FPU_USED 3
+
+struct netbsd32_arm_sync_icache_args {
+ netbsd32_uintptr_t addr; /* Virtual start address */
+ netbsd32_size_t len; /* Region size */
+};
#endif /* _MACHINE_NETBSD32_H_ */
Index: src/sys/arch/aarch64/include/pmap.h
diff -u src/sys/arch/aarch64/include/pmap.h:1.13 src/sys/arch/aarch64/include/pmap.h:1.14
--- src/sys/arch/aarch64/include/pmap.h:1.13 Fri Oct 12 00:57:17 2018
+++ src/sys/arch/aarch64/include/pmap.h Fri Oct 12 01:28:58 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.13 2018/10/12 00:57:17 ryo Exp $ */
+/* $NetBSD: pmap.h,v 1.14 2018/10/12 01:28:58 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -248,6 +248,7 @@ aarch64_mmap_flags(paddr_t mdpgno)
#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
bool pmap_extract_coherency(pmap_t, vaddr_t, paddr_t *, bool *);
+void pmap_icache_sync_range(pmap_t, vaddr_t, vaddr_t);
#define PMAP_MAPSIZE1 L2_SIZE
Index: src/sys/arch/aarch64/include/vmparam.h
diff -u src/sys/arch/aarch64/include/vmparam.h:1.6 src/sys/arch/aarch64/include/vmparam.h:1.7
--- src/sys/arch/aarch64/include/vmparam.h:1.6 Fri Sep 14 05:37:42 2018
+++ src/sys/arch/aarch64/include/vmparam.h Fri Oct 12 01:28:58 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: vmparam.h,v 1.6 2018/09/14 05:37:42 ryo Exp $ */
+/* $NetBSD: vmparam.h,v 1.7 2018/10/12 01:28:58 ryo Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
#endif
#ifndef MAXDSIZ32
-#define MAXDSIZ32 (1536*1024*1024) /* max data size */
+#define MAXDSIZ32 (3U*1024*1024*1024) /* max data size */
#endif
#ifndef MAXSSIZ32
@@ -116,7 +116,7 @@
#define VM_MAXUSER_ADDRESS ((vaddr_t) (1L << 48) - PAGE_SIZE)
#define VM_MAX_ADDRESS VM_MAXUSER_ADDRESS
-#define VM_MAXUSER_ADDRESS32 ((vaddr_t) 0x7ffff000)
+#define VM_MAXUSER_ADDRESS32 ((vaddr_t) 0xfffff000)
/*
* Give ourselves 64GB of mappable kernel space. That leaves the rest
@@ -137,6 +137,11 @@
#define USRIOSIZE (PAGE_SIZE / 8)
#define VM_PHYS_SIZE (USRIOSIZE * PAGE_SIZE)
+#define VM_DEFAULT_ADDRESS32_TOPDOWN(da, sz) \
+ trunc_page(USRSTACK32 - MAXSSIZ32 - (sz) - user_stack_guard_size)
+#define VM_DEFAULT_ADDRESS32_BOTTOMUP(da, sz) \
+ round_page((vaddr_t)(da) + (vsize_t)MAXDSIZ32)
+
/*
* Since we have the address space, we map all of physical memory (RAM)
* using block page table entries.
Index: src/sys/arch/arm/include/mcontext.h
diff -u src/sys/arch/arm/include/mcontext.h:1.20 src/sys/arch/arm/include/mcontext.h:1.21
--- src/sys/arch/arm/include/mcontext.h:1.20 Sun Apr 1 04:35:04 2018
+++ src/sys/arch/arm/include/mcontext.h Fri Oct 12 01:28:58 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: mcontext.h,v 1.20 2018/04/01 04:35:04 ryo Exp $ */
+/* $NetBSD: mcontext.h,v 1.21 2018/10/12 01:28:58 ryo Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -142,7 +142,7 @@ typedef struct {
/* Compat structures */
typedef struct {
-#ifdef __ARM_EABI__
+#if 1 /* __ARM_EABI__ is default on aarch64 */
unsigned int __vfp_fpscr;
uint64_t __vfp_fstmx[32];
unsigned int __vfp_fpsid;
Index: src/sys/arch/evbarm/conf/GENERIC64
diff -u src/sys/arch/evbarm/conf/GENERIC64:1.43 src/sys/arch/evbarm/conf/GENERIC64:1.44
--- src/sys/arch/evbarm/conf/GENERIC64:1.43 Wed Oct 3 06:02:33 2018
+++ src/sys/arch/evbarm/conf/GENERIC64 Fri Oct 12 01:28:58 2018
@@ -1,5 +1,5 @@
#
-# $NetBSD: GENERIC64,v 1.43 2018/10/03 06:02:33 skrll Exp $
+# $NetBSD: GENERIC64,v 1.44 2018/10/12 01:28:58 ryo Exp $
#
# GENERIC ARM (aarch64) kernel
#
@@ -89,6 +89,9 @@ makeoptions COPY_SYMTAB=1
config netbsd root on ? type ?
+options COMPAT_NETBSD32
+options EXEC_ELF32
+
# Device tree support
armfdt0 at root
simplebus* at fdt? pass 0
Index: src/sys/arch/evbarm/conf/RPI64
diff -u src/sys/arch/evbarm/conf/RPI64:1.7 src/sys/arch/evbarm/conf/RPI64:1.8
--- src/sys/arch/evbarm/conf/RPI64:1.7 Wed Aug 1 20:04:11 2018
+++ src/sys/arch/evbarm/conf/RPI64 Fri Oct 12 01:28:58 2018
@@ -1,5 +1,5 @@
#
-# $NetBSD: RPI64,v 1.7 2018/08/01 20:04:11 maxv Exp $
+# $NetBSD: RPI64,v 1.8 2018/10/12 01:28:58 ryo Exp $
#
# RPI64 - Raspberry Pi 3 and Pi 2 v1.2 in AARCH64 mode
#
@@ -61,6 +61,9 @@ options LOCKDEBUG
config netbsd root on ? type ?
+options COMPAT_NETBSD32
+options EXEC_ELF32
+
# Device tree support
armfdt0 at root
simplebus* at fdt? pass 0
Added files:
Index: src/sys/arch/aarch64/aarch64/aarch32_syscall.c
diff -u /dev/null src/sys/arch/aarch64/aarch64/aarch32_syscall.c:1.1
--- /dev/null Fri Oct 12 01:28:58 2018
+++ src/sys/arch/aarch64/aarch64/aarch32_syscall.c Fri Oct 12 01:28:57 2018
@@ -0,0 +1,191 @@
+/* $NetBSD: aarch32_syscall.c,v 1.1 2018/10/12 01:28:57 ryo Exp $ */
+
+/*
+ * Copyright (c) 2018 Ryo Shimizu <[email protected]>
+ * 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.
+ *
+ * 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: aarch32_syscall.c,v 1.1 2018/10/12 01:28:57 ryo Exp $");
+
+#include "opt_multiprocessor.h"
+
+#include <sys/param.h>
+#include <sys/ktrace.h>
+#include <sys/proc.h>
+#include <sys/syscallvar.h>
+#include <uvm/uvm_extern.h>
+
+#include <aarch64/userret.h>
+#include <aarch64/frame.h>
+#include <aarch64/armreg.h>
+
+#ifndef EMULNAME
+#error EMULNAME is not defined
+#endif
+
+#ifndef NARGREG
+#define NARGREG 4 /* 4 args are in registers */
+#endif
+
+static void EMULNAME(syscall)(struct trapframe *);
+
+union args {
+ register_t a64[EMULNAMEU(SYS_MAXSYSARGS)];
+ register32_t a32[EMULNAMEU(SYS_MAXSYSARGS)];
+};
+
+void
+EMULNAME(syscall)(struct trapframe *tf)
+{
+ struct lwp * const l = curlwp;
+ struct proc * const p = l->l_proc;
+ const struct sysent *callp;
+ union args args64buf, args32buf;
+ register_t rval[2];
+ register32_t *args32 = args32buf.a32;
+ int error, i;
+ bool do_trace;
+
+ LWP_CACHE_CREDS(l, p);
+
+ curcpu()->ci_data.cpu_nsyscall++;
+
+ uint32_t code = tf->tf_esr & 0xffff; /* XXX: 16-23bits are omitted */
+
+ /*
+ * XXX: for netbsd32 emulation, SWI_OS_NETBSD should be checked?
+ * 16-23bits of imm of swi is omitted. need to read insn?
+ */
+#ifdef THUMB_CODE
+#error notyet
+ if (tf->tf_spsr & SPSR_A32_T) {
+ code |= tf->tf_reg[0];
+ tf->tf_reg[0] = tf->tf_reg[12]; /* r0 = ip(r12) */
+ }
+#endif
+
+ int nargs_reg = NARGREG; /* number of argument in registers */
+ int regstart = 0; /* args start from r0 */
+
+ code %= EMULNAMEU(SYS_NSYSENT);
+ callp = p->p_emul->e_sysent + code;
+ if (__predict_false(callp->sy_flags & SYCALL_INDIRECT)) {
+ nargs_reg -= 1;
+ regstart = 1; /* args start from r1 */
+ code = tf->tf_reg[0] % EMULNAMEU(SYS_NSYSENT);
+ callp = p->p_emul->e_sysent + code;
+
+ /* don't allow nested syscall */
+ if (__predict_false(callp->sy_flags & SYCALL_INDIRECT)) {
+ error = EINVAL;
+ goto bad;
+ }
+ }
+
+ /* number of argument to fetch from sp */
+ KASSERT(callp->sy_narg <= EMULNAMEU(SYS_MAXSYSARGS));
+ int nargs_sp = callp->sy_narg - nargs_reg;
+
+ /* fetch arguments from tf and sp, and store to args32buf[] */
+ for (i = 0; i < nargs_reg; i++)
+ *args32++ = (uint32_t)tf->tf_reg[regstart++];
+ if (nargs_sp > 0) {
+ error = copyin(
+ (void*)(uintptr_t)(uint32_t)tf->tf_reg[13], /* sp = r13 */
+ args32, nargs_sp * sizeof(register32_t));
+ if (error)
+ goto bad;
+ }
+
+ rval[0] = rval[1] = 0;
+
+#if 0
+ error = sy_invoke(callp, l, args32buf.a32, rval, code);
+#else
+ /*
+ * XXX: trace_enter()/trace_exit() called from sy_invoke() expects
+ * 64bit args, but sy_invoke doesn't take care of it.
+ * therefore call trace_enter(), sy_call(), trace_exit() manually.
+ */
+#ifdef KDTRACE_HOOKS
+#define KDTRACE_ENTRY(a) (a)
+#else
+#define KDTRACE_ENTRY(a) (0)
+#endif
+ do_trace = p->p_trace_enabled &&
+ ((callp->sy_flags & SYCALL_INDIRECT) == 0);
+ if (__predict_false(do_trace ||
+ KDTRACE_ENTRY(callp->sy_entry) || KDTRACE_ENTRY(callp->sy_return))) {
+ /* build 64bit args for trace_enter()/trace_exit() */
+ int nargs = callp->sy_narg;
+ for (i = 0; i < nargs; i++)
+ args64buf.a64[i] = args32buf.a32[i];
+ }
+
+ if (__predict_false(do_trace || KDTRACE_ENTRY(callp->sy_entry)))
+ error = trace_enter(code, callp, args64buf.a64);
+
+ if (error == 0)
+ error = sy_call(callp, l, args32buf.a32, rval);
+
+ if (__predict_false(do_trace || KDTRACE_ENTRY(callp->sy_return)))
+ trace_exit(code, callp, args64buf.a64, rval, error);
+#endif
+
+ if (__predict_true(error == 0)) {
+ tf->tf_reg[0] = rval[0];
+ tf->tf_reg[1] = rval[1];
+ tf->tf_spsr &= ~NZCV_C;
+ } else {
+ switch (error) {
+ case ERESTART:
+ /* redo system call insn */
+ tf->tf_pc -= 4;
+ break;
+ case EJUSTRETURN:
+ /* nothing to do */
+ break;
+ default:
+ bad:
+#ifndef __HAVE_MINIMAL_EMUL
+ if (p->p_emul->e_errno)
+ error = p->p_emul->e_errno[error];
+#endif
+ tf->tf_reg[0] = error;
+ tf->tf_spsr |= NZCV_C;
+ break;
+ }
+ }
+
+ userret(l);
+}
+
+void EMULNAME(syscall_intern)(struct proc *);
+
+void
+EMULNAME(syscall_intern)(struct proc *p)
+{
+ p->p_md.md_syscall = EMULNAME(syscall);
+}
Index: src/sys/arch/aarch64/aarch64/netbsd32_syscall.c
diff -u /dev/null src/sys/arch/aarch64/aarch64/netbsd32_syscall.c:1.1
--- /dev/null Fri Oct 12 01:28:58 2018
+++ src/sys/arch/aarch64/aarch64/netbsd32_syscall.c Fri Oct 12 01:28:57 2018
@@ -0,0 +1,39 @@
+/* $NetBSD: netbsd32_syscall.c,v 1.1 2018/10/12 01:28:57 ryo Exp $ */
+
+/*
+ * Copyright (c) 2018 Ryo Shimizu <[email protected]>
+ * 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.
+ *
+ * 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_syscall.c,v 1.1 2018/10/12 01:28:57 ryo Exp $");
+
+#include "opt_compat_netbsd32.h"
+
+#include <compat/netbsd32/netbsd32_syscall.h>
+
+#define EMULNAME(x) __CONCAT(netbsd32_,x)
+#define EMULNAMEU(x) __CONCAT(NETBSD32_,x)
+
+#include "aarch32_syscall.c"