COMPAT_NETBSD32 to work on also thumbmode

This commit is contained in:
ryo 2019-04-12 09:29:26 +00:00
parent 2eeee3a428
commit 25f00d5999
3 changed files with 33 additions and 26 deletions

View File

@ -1,8 +1,7 @@
$NetBSD: TODO,v 1.5 2019/04/10 06:58:12 ryo Exp $
$NetBSD: TODO,v 1.6 2019/04/12 09:29:26 ryo Exp $
TODO list for NetBSD/aarch64
- kernel preemption
- Implement __HAVE_UCAS_FULL or __HAVE_UCAS_MP (don't use full generic impl)
- pmap should be work even if PID_MAX >= 65536 (don't depend 16bit ASID)
- TLB ASID in pmap should be randomized
- COMPAT_NETBSD32 for thumb mode

View File

@ -1,4 +1,4 @@
/* $NetBSD: aarch32_syscall.c,v 1.2 2019/03/01 02:40:01 mrg Exp $ */
/* $NetBSD: aarch32_syscall.c,v 1.3 2019/04/12 09:29:26 ryo Exp $ */
/*
* Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: aarch32_syscall.c,v 1.2 2019/03/01 02:40:01 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: aarch32_syscall.c,v 1.3 2019/04/12 09:29:26 ryo Exp $");
#include <sys/param.h>
#include <sys/ktrace.h>
@ -35,9 +35,10 @@ __KERNEL_RCSID(0, "$NetBSD: aarch32_syscall.c,v 1.2 2019/03/01 02:40:01 mrg Exp
#include <sys/syscallvar.h>
#include <uvm/uvm_extern.h>
#include <aarch64/userret.h>
#include <aarch64/frame.h>
#include <aarch64/armreg.h>
#include <aarch64/frame.h>
#include <aarch64/machdep.h>
#include <aarch64/userret.h>
#ifndef EMULNAME
#error EMULNAME is not defined
@ -64,29 +65,29 @@ EMULNAME(syscall)(struct trapframe *tf)
register_t rval[2];
register32_t *args32 = args32buf.a32;
int error, i;
bool do_trace;
bool do_trace, thumbmode;
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) */
thumbmode = (tf->tf_spsr & SPSR_A32_T) ? true : false;
if (thumbmode) {
if (code != 255) {
do_trapsignal(l, SIGILL, ILL_ILLTRP,
(void *)(tf->tf_pc - 2), tf->tf_esr);
error = EINVAL;
goto bad;
}
code = tf->tf_reg[0];
tf->tf_reg[0] = tf->tf_reg[12]; /* orig $r0 is saved to $ip */
}
#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)) {
@ -160,7 +161,10 @@ EMULNAME(syscall)(struct trapframe *tf)
switch (error) {
case ERESTART:
/* redo system call insn */
tf->tf_pc -= 4;
if (thumbmode)
tf->tf_pc -= 2;
else
tf->tf_pc -= 4;
break;
case EJUSTRETURN:
/* nothing to do */

View File

@ -1,4 +1,4 @@
/* $NetBSD: netbsd32_machdep.c,v 1.5 2019/01/27 19:13:04 alnsn Exp $ */
/* $NetBSD: netbsd32_machdep.c,v 1.6 2019/04/12 09:29:26 ryo Exp $ */
/*
* Copyright (c) 2018 Ryo Shimizu <ryo@nerv.org>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.5 2019/01/27 19:13:04 alnsn Exp $");
__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.6 2019/04/12 09:29:26 ryo Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@ -88,10 +88,9 @@ netbsd32_setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
tf->tf_spsr = SPSR_M_USR32;
#endif
#ifdef THUMB_CODE
/* 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 */
@ -119,6 +118,10 @@ netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs)
regs->r_pc = tf->tf_pc; /* r15 = pc */
regs->r_cpsr = tf->tf_spsr;
/* THUMB CODE? */
if (tf->tf_spsr & SPSR_A32_T)
regs->r_pc |= 1;
return 0;
}
@ -258,12 +261,13 @@ netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
/* 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)
/* THUMB CODE? */
if (((uintptr_t)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 */