Author: ed
Date: Thu Nov 30 17:58:48 2017
New Revision: 326406
URL: https://svnweb.freebsd.org/changeset/base/326406

Log:
  Port cloudabi32.ko to FreeBSD/arm64.
  
  This change adds an implementation of a sysent for running CloudABI
  armv6 and armv7 binaries on FreeBSD/arm64. It is a somewhat literal copy
  of the armv6 version, except that it's been patched up to use the proper
  registers.
  
  Just like for cloudabi32.ko on FreeBSD/amd64, we make use of a vDSO that
  automatically pads system call parameters to 64-bit value. These are
  stored in a buffer on the stack, meaning we need to use copyin() and
  copyout() unconditionally.

Added:
  head/sys/arm64/cloudabi32/
     - copied from r326229, head/sys/arm/cloudabi32/
Modified:
  head/share/man/man4/cloudabi.4
  head/sys/arm64/cloudabi32/cloudabi32_sysvec.c
  head/sys/conf/files.arm64
  head/sys/modules/Makefile

Modified: head/share/man/man4/cloudabi.4
==============================================================================
--- head/share/man/man4/cloudabi.4      Thu Nov 30 15:58:38 2017        
(r326405)
+++ head/share/man/man4/cloudabi.4      Thu Nov 30 17:58:48 2017        
(r326406)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/
+.\" Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -22,7 +22,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\" $FreeBSD$
-.Dd September 22, 2016
+.Dd November 30, 2017
 .Dt CLOUDABI 4
 .Os
 .Sh NAME
@@ -84,7 +84,7 @@ module can be loaded on any architecture supported by
 .Fx ,
 the
 .Nm cloudabi32
-module is only available on amd64, armv6 and i386.
+module is only available on amd64, arm64, armv6, armv7 and i386.
 The same holds for the
 .Nm cloudabi64
 module,

Modified: head/sys/arm64/cloudabi32/cloudabi32_sysvec.c
==============================================================================
--- head/sys/arm/cloudabi32/cloudabi32_sysvec.c Sun Nov 26 14:53:56 2017        
(r326229)
+++ head/sys/arm64/cloudabi32/cloudabi32_sysvec.c       Thu Nov 30 17:58:48 
2017        (r326406)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015-2016 Nuxi, https://nuxi.nl/
+ * Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,16 +53,13 @@ cloudabi32_proc_setregs(struct thread *td, struct imag
 {
        struct trapframe *regs;
 
-       exec_setregs(td, imgp, stack);
-
-       /*
-        * The stack now contains a pointer to the TCB and the auxiliary
-        * vector. Let r0 point to the auxiliary vector, and set
-        * tpidrurw to the TCB.
-        */
        regs = td->td_frame;
-       regs->tf_r0 =
+       memset(regs, 0, sizeof(*regs));
+       regs->tf_x[0] =
            stack + roundup(sizeof(cloudabi32_tcb_t), sizeof(register_t));
+       regs->tf_x[13] = STACKALIGN(stack);
+       regs->tf_elr = imgp->entry_addr;
+       regs->tf_spsr |= PSR_AARCH32;
        (void)cpu_set_user_tls(td, TO_PTR(stack));
 }
 
@@ -77,27 +74,30 @@ cloudabi32_fetch_syscall_args(struct thread *td)
        sa = &td->td_sa;
 
        /* Obtain system call number. */
-       sa->code = frame->tf_r12;
+       sa->code = frame->tf_x[0];
        if (sa->code >= CLOUDABI32_SYS_MAXSYSCALL)
                return (ENOSYS);
        sa->callp = &cloudabi32_sysent[sa->code];
        sa->narg = sa->callp->sy_narg;
 
-       /* Fetch system call arguments from registers and the stack. */
-       sa->args[0] = frame->tf_r0;
-       sa->args[1] = frame->tf_r1;
-       sa->args[2] = frame->tf_r2;
-       sa->args[3] = frame->tf_r3;
-       if (sa->narg > 4) {
-               error = copyin((void *)td->td_frame->tf_usr_sp, &sa->args[4],
-                   (sa->narg - 4) * sizeof(register_t));
-               if (error != 0)
-                       return (error);
-       }
+       /*
+        * Fetch system call arguments.
+        *
+        * The vDSO has already made sure that the arguments are
+        * eight-byte aligned. Pointers and size_t parameters are
+        * zero-extended. This makes it possible to copy in the
+        * arguments directly. As long as the call doesn't use 32-bit
+        * data structures, we can just invoke the same system call
+        * implementation used by 64-bit processes.
+        */
+       error = copyin((void *)frame->tf_x[2], sa->args,
+           sa->narg * sizeof(sa->args[0]));
+       if (error != 0)
+               return (error);
 
        /* Default system call return values. */
        td->td_retval[0] = 0;
-       td->td_retval[1] = frame->tf_r1;
+       td->td_retval[1] = 0;
        return (0);
 }
 
@@ -108,20 +108,32 @@ cloudabi32_set_syscall_retval(struct thread *td, int e
 
        switch (error) {
        case 0:
-               /* System call succeeded. */
-               frame->tf_r0 = td->td_retval[0];
-               frame->tf_r1 = td->td_retval[1];
-               frame->tf_spsr &= ~PSR_C;
+               /*
+                * System call succeeded.
+                *
+                * Simply copy out the 64-bit return values into the
+                * same buffer provided for system call arguments. The
+                * vDSO will copy them to the right spot, truncating
+                * pointers and size_t values to 32 bits.
+                */
+               if (copyout(td->td_retval, (void *)frame->tf_x[2],
+                   sizeof(td->td_retval)) == 0) {
+                       frame->tf_x[0] = 0;
+                       frame->tf_spsr &= ~PSR_C;
+               } else {
+                       frame->tf_x[0] = CLOUDABI_EFAULT;
+                       frame->tf_spsr |= PSR_C;
+               }
                break;
        case ERESTART:
                /* Restart system call. */
-               frame->tf_pc -= 4;
+               frame->tf_elr -= 4;
                break;
        case EJUSTRETURN:
                break;
        default:
                /* System call returned an error. */
-               frame->tf_r0 = cloudabi_convert_errno(error);
+               frame->tf_x[0] = cloudabi_convert_errno(error);
                frame->tf_spsr |= PSR_C;
                break;
        }
@@ -131,16 +143,15 @@ static void
 cloudabi32_schedtail(struct thread *td)
 {
        struct trapframe *frame = td->td_frame;
+       register_t retval[2];
 
-       /*
-        * Initial register values for processes returning from fork.
-        * Make sure that we only set these values when forking, not
-        * when creating a new thread.
-        */
+       /* Return values for processes returning from fork. */
        if ((td->td_pflags & TDP_FORKING) != 0) {
-               frame->tf_r0 = CLOUDABI_PROCESS_CHILD;
-               frame->tf_r1 = td->td_tid;
+               retval[0] = CLOUDABI_PROCESS_CHILD;
+               retval[1] = td->td_tid;
+               copyout(retval, (void *)frame->tf_x[2], sizeof(retval));
        }
+       frame->tf_spsr |= PSR_AARCH32;
 }
 
 int
@@ -148,21 +159,18 @@ cloudabi32_thread_setregs(struct thread *td,
     const cloudabi32_threadattr_t *attr, uint32_t tcb)
 {
        struct trapframe *frame;
-       stack_t stack;
 
-       /* Perform standard register initialization. */
-       stack.ss_sp = TO_PTR(attr->stack);
-       stack.ss_size = attr->stack_len;
-       cpu_set_upcall(td, TO_PTR(attr->entry_point), NULL, &stack);
-
        /*
         * Pass in the thread ID of the new thread and the argument
         * pointer provided by the parent thread in as arguments to the
         * entry point.
         */
        frame = td->td_frame;
-       frame->tf_r0 = td->td_tid;
-       frame->tf_r1 = attr->argument;
+       memset(frame, 0, sizeof(*frame));
+       frame->tf_x[0] = td->td_tid;
+       frame->tf_x[1] = attr->argument;
+       frame->tf_x[13] = STACKALIGN(attr->stack + attr->stack_len);
+       frame->tf_elr = attr->entry_point;
 
        /* Set up TLS. */
        return (cpu_set_user_tls(td, TO_PTR(tcb)));
@@ -176,7 +184,7 @@ static struct sysentvec cloudabi32_elf_sysvec = {
        .sv_coredump            = elf32_coredump,
        .sv_pagesize            = PAGE_SIZE,
        .sv_minuser             = VM_MIN_ADDRESS,
-       .sv_maxuser             = VM_MAXUSER_ADDRESS,
+       .sv_maxuser             = (uintmax_t)1 << 32,
        .sv_stackprot           = VM_PROT_READ | VM_PROT_WRITE,
        .sv_copyout_strings     = cloudabi32_copyout_strings,
        .sv_setregs             = cloudabi32_proc_setregs,

Modified: head/sys/conf/files.arm64
==============================================================================
--- head/sys/conf/files.arm64   Thu Nov 30 15:58:38 2017        (r326405)
+++ head/sys/conf/files.arm64   Thu Nov 30 17:58:48 2017        (r326406)
@@ -1,4 +1,16 @@
 # $FreeBSD$
+cloudabi32_vdso.o              optional        compat_cloudabi32       \
+       dependency      "$S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S"    
\
+       compile-with    "${CC} -x assembler-with-cpp -m32 -shared -nostdinc 
-nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds 
$S/contrib/cloudabi/cloudabi_vdso_armv6_on_64bit.S -o ${.TARGET}" \
+       no-obj no-implicit-rule                                         \
+       clean           "cloudabi32_vdso.o"
+#
+cloudabi32_vdso_blob.o         optional        compat_cloudabi32       \
+       dependency      "cloudabi32_vdso.o"                     \
+       compile-with    "${OBJCOPY} --input-target binary --output-target 
elf64-littleaarch64 --binary-architecture aarch64 cloudabi32_vdso.o ${.TARGET}" 
\
+       no-implicit-rule                                                \
+       clean           "cloudabi32_vdso_blob.o"
+#
 cloudabi64_vdso.o              optional        compat_cloudabi64       \
        dependency      "$S/contrib/cloudabi/cloudabi_vdso_aarch64.S"   \
        compile-with    "${CC} -x assembler-with-cpp -shared -nostdinc 
-nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds 
$S/contrib/cloudabi/cloudabi_vdso_aarch64.S -o ${.TARGET}" \
@@ -130,6 +142,7 @@ arm64/cavium/thunder_pcie_fdt.c             optional        
soc_cavm_thu
 arm64/cavium/thunder_pcie_pem.c                optional        
soc_cavm_thunderx pci
 arm64/cavium/thunder_pcie_pem_fdt.c    optional        soc_cavm_thunderx pci 
fdt
 arm64/cavium/thunder_pcie_common.c     optional        soc_cavm_thunderx pci
+arm64/cloudabi32/cloudabi32_sysvec.c   optional compat_cloudabi32
 arm64/cloudabi64/cloudabi64_sysvec.c   optional compat_cloudabi64
 contrib/vchiq/interface/compat/vchi_bsd.c      optional vchiq soc_brcm_bcm2837 
\
        compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 
-I$S/contrib/vchiq"

Modified: head/sys/modules/Makefile
==============================================================================
--- head/sys/modules/Makefile   Thu Nov 30 15:58:38 2017        (r326405)
+++ head/sys/modules/Makefile   Thu Nov 30 17:58:48 2017        (r326406)
@@ -796,8 +796,8 @@ _em=                em
 _epic=         epic
 .endif
 
-.if (${MACHINE_CPUARCH} == "amd64" || ${MACHINE_ARCH:Marmv[67]*} != "" || \
-     ${MACHINE_CPUARCH} == "i386")
+.if (${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \
+     ${MACHINE_ARCH:Marmv[67]*} != "" || ${MACHINE_CPUARCH} == "i386")
 _cloudabi32=   cloudabi32
 .endif
 .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64"
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to