@@ -30,7 +30,8 @@ export OBJDUMP := $(KLIBCROSS)objdump
NOSTDINC_FLAGS := -nostdlib -nostdinc -isystem $(shell $(CC) -print-file-name=include)
-ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/parisc64/parisc/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/sh.*/sh/)
+ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/parisc64/parisc/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ \
+ -e s/aarch64.*/arm64/ -e s/sh.*/sh/)
export KLIBCARCH ?= $(ARCH)
export KLIBCARCHDIR := $(shell echo $(KLIBCARCH) | sed -e s/s390x/s390/)
new file mode 100644
@@ -0,0 +1,17 @@
+/*
+ * include/arch/arm64/klibc/archconfig.h
+ *
+ * See include/klibc/sysconfig.h for the options that can be set in
+ * this file.
+ *
+ */
+
+#ifndef _KLIBC_ARCHCONFIG_H
+#define _KLIBC_ARCHCONFIG_H
+
+/* Use rt_* signals */
+#define _KLIBC_USE_RT_SIG 1
+#define _KLIBC_NO_MMU 0
+#define _KLIBC_REAL_VFORK 1
+
+#endif /* _KLIBC_ARCHCONFIG_H */
new file mode 100644
@@ -0,0 +1,22 @@
+/*
+ * arch/arm64/include/klibc/archsetjmp.h
+ */
+
+#ifndef _KLIBC_ARCHSETJMP_H
+#define _KLIBC_ARCHSETJMP_H
+
+/*
+ * x19-x28 are callee saved, also save fp, lr, sp.
+ * d8-d15 are unused as we specify -mgeneral-regs-only as a build flag.
+ */
+
+struct __jmp_buf {
+ uint64_t __x19, __x20, __x21, __x22;
+ uint64_t __x23, __x24, __x25, __x26;
+ uint64_t __x27, __x28, __x29, __x30;
+ uint64_t __sp;
+};
+
+typedef struct __jmp_buf jmp_buf[1];
+
+#endif /* _SETJMP_H */
new file mode 100644
@@ -0,0 +1,14 @@
+/*
+ * arch/arm64/include/klibc/archsignal.h
+ *
+ * Architecture-specific signal definitions
+ *
+ */
+
+#ifndef _KLIBC_ARCHSIGNAL_H
+#define _KLIBC_ARCHSIGNAL_H
+
+#include <asm/signal.h>
+/* No special stuff for this architecture */
+
+#endif
new file mode 100644
@@ -0,0 +1,29 @@
+#ifndef _KLIBC_ARCHSTAT_H
+#define _KLIBC_ARCHSTAT_H
+
+#include <klibc/stathelp.h>
+
+struct stat {
+ unsigned long st_dev; /* Device. */
+ unsigned long st_ino; /* File serial number. */
+ unsigned int st_mode; /* File mode. */
+ unsigned int st_nlink; /* Link count. */
+ unsigned int st_uid; /* User ID of the file's owner. */
+ unsigned int st_gid; /* Group ID of the file's group. */
+ unsigned long st_rdev; /* Device number, if device. */
+ unsigned long __pad1;
+ long st_size; /* Size of file, in bytes. */
+ int st_blksize; /* Optimal block size for I/O. */
+ int __pad2;
+ long st_blocks; /* Number 512-byte blocks allocated. */
+ long st_atime; /* Time of last access. */
+ unsigned long st_atime_nsec;
+ long st_mtime; /* Time of last modification. */
+ unsigned long st_mtime_nsec;
+ long st_ctime; /* Time of last status change. */
+ unsigned long st_ctime_nsec;
+ unsigned int __unused4;
+ unsigned int __unused5;
+ };
+
+#endif
new file mode 100644
@@ -0,0 +1,11 @@
+/*
+ * usr/include/arch/arm64/klibc/asmmacros.h
+ *
+ * Assembly macros used by arm64 system call stubs
+ */
+
+#ifndef _KLIBC_ASMMACROS_H
+#define _KLIBC_ASMMACROS_H
+
+
+#endif /* _KLIBC_ASMMACROS_H */
@@ -36,6 +36,7 @@ b) If you're cross-compiling, you need to set KLIBCARCH to the
arm-thumb: Untested
arm: Working
arm26: Not yet ported
+ arm64: Working
avr32: Not yet ported
cris: Working
h8300: Not yet ported
@@ -21,7 +21,7 @@ void _exit,exit::_exit(int);
<?!ia64> pid_t clone::__clone(unsigned long, void *);
<?ia64> pid_t clone::__clone2(unsigned long, void *, void *);
# if ! _KLIBC_NO_MMU
-<!sparc,sparc64,ia64> pid_t fork();
+<!sparc,sparc64,ia64,arm64> pid_t fork();
<sparc,sparc64> pid_t fork@forkish();
#endif
#if _KLIBC_REAL_VFORK
new file mode 100644
@@ -0,0 +1,7 @@
+
+# klibc files for arm64
+#
+
+klib-y := setjmp.o syscall.o vfork.o
+always := crt0.o
+targets := crt0.o
new file mode 100644
@@ -0,0 +1,23 @@
+# -*- makefile -*-
+#
+# arch/arm64/MCONFIG
+#
+# Special rules for this architecture. Note that this is actually
+# included from the main Makefile, and that pathnames should be
+# accordingly.
+#
+
+CPU_ARCH ?= armv8-a
+CPU_TUNE ?= generic
+
+KLIBCOPTFLAGS += -g -Os -march=$(CPU_ARCH) -mtune=$(CPU_TUNE)
+KLIBCBITSIZE = 64
+KLIBCREQFLAGS += -fno-exceptions -mgeneral-regs-only
+
+# Extra linkflags when building the shared version of the library
+# This address needs to be reachable using normal inter-module
+# calls, and work on the memory models for this architecture
+
+# On arm64, binaries are normally loaded at 4MB. Place klibc.so
+# a little before that at 2MB to prevent overlap.
+KLIBCSHAREDFLAGS = -Ttext 0x0200000
new file mode 100644
@@ -0,0 +1,19 @@
+#
+# arch/arm64/crt0.S
+#
+# void _start(void)
+# {
+# __libc_init(elf_structure, atexit_ptr);
+# }
+#
+
+ .text
+ .balign 8
+ .type _start,#function
+ .globl _start
+
+_start:
+ mov x0, sp
+ mov x1, #0
+ bl __libc_init
+ .size _start,.-_start
new file mode 100644
@@ -0,0 +1,47 @@
+#
+# arch/arm64/setjmp.S
+#
+# setjmp/longjmp for arm64
+#
+
+#include <klibc/asmmacros.h>
+
+# we specify -mgeneral-regs-only as a build flag thus do not need to
+# save d8-d15
+
+ .text
+ .balign 8
+ .globl setjmp
+ .type setjmp, #function
+setjmp:
+ mov x1, sp
+ stp x19, x20, [x0, #0]
+ stp x21, x22, [x0, #16]
+ stp x23, x24, [x0, #32]
+ stp x25, x26, [x0, #48]
+ stp x27, x28, [x0, #64]
+ stp x29, x30, [x0, #80]
+ str x1, [x0, #96]
+ mov x0, #0 /* set the return value of setjmp */
+ br x30
+ .size setjmp,.-setjmp
+
+ .text
+ .balign 8
+ .globl longjmp
+ .type longjmp, #function
+longjmp:
+ ldp x19, x20, [x0, #0]
+ ldp x21, x22, [x0, #16]
+ ldp x23, x24, [x0, #32]
+ ldp x25, x26, [x0, #48]
+ ldp x27, x28, [x0, #64]
+ ldp x29, x30, [x0, #80]
+ ldr x2, [x0, #96]
+ mov sp, x2
+ mov x0, x1
+ cbnz x1, 1f
+ mov x0, #1
+1:
+ br x30
+ .size longjmp,.-longjmp
new file mode 100644
@@ -0,0 +1,25 @@
+/*
+ * arch/arm64/syscall.S
+ *
+ * System call common handling - if the return
+ * value from the system call is negative, then
+ * extract the magnitude and return it as errno and
+ * return -1, if the return value is 0 that is
+ * success case.
+ */
+
+ .type __syscall_common,#function
+ .globl __syscall_common
+ .balign 8
+
+__syscall_common:
+ cmp x0, #0x0
+ b.ge 2f
+ neg x0, x0
+ ldr x8, 1f
+ str x0, [x8]
+ mov x0, #-1
+2:
+ ret
+1:
+ .dword errno
new file mode 100644
@@ -0,0 +1,25 @@
+# -*- perl -*-
+#
+# arch/arm64/sysstub.ph
+#
+# Script to generate system call stubs
+#
+
+sub make_sysstub($$$$$@) {
+ my($outputdir, $fname, $type, $sname, $stype, @args) = @_;
+
+ open(OUT, '>', "${outputdir}/${fname}.S");
+ print OUT "#include <asm/unistd.h>\n";
+ print OUT "#include <klibc/asmmacros.h>\n";
+ print OUT " .text\n";
+ print OUT " .type ${fname}, #function\n";
+ print OUT " .globl ${fname}\n";
+ print OUT " .balign 8\n";
+ print OUT "${fname}:\n";
+ print OUT " mov w8,__NR_${sname}\n";
+ print OUT " svc 0\n";
+ print OUT " b __syscall_common\n";
+ print OUT " .size ${fname},.-${fname}\n";
+}
+
+1;
new file mode 100644
@@ -0,0 +1,34 @@
+/*
+ * arch/arm64/vfork.S
+ *
+ * vfork - a system call which must not use the stack.
+ */
+
+#include <klibc/asmmacros.h>
+#include <asm/unistd.h>
+
+ .type vfork,#function
+ .globl vfork
+ .balign 8
+
+vfork:
+ /* Prepare for the system call */
+ /* 1. Push the function pointer and argument location
+ on to the child process stack */
+ /* 2. Gather the Flags */
+ /* New sp is already in x1. */
+ mov x0, #0x4111 /* CLONE_VM | CLONE_VFORK | SIGCHLD */
+ mov x1, sp
+ mov w8,__NR_clone
+ svc 0
+ cmp x0, #0x0
+ b.ge 2f
+ neg x0, x0
+ ldr x8, 1f
+ str x0, [x8]
+ mov x0, #-1
+2:
+ ret
+1:
+ .dword errno
+ .size vfork,.-vfork
Based on work by Neil Williams (codehelp@debian.org) and Anil Singhar (anil.singhar@linaro.org), this patch introduces arm64 support. Originally-by: Neil Williams <codehelp@debian.org> Originally-by: Anil Singhar <anil.singhar@linaro.org> Signed-off-by: Steve Capper <steve.capper@linaro.org> --- Changes in V2: fp regs removed from setjmp/longjmp (mgeneral-regs-only build flags used to stop fp regs being used). --- Makefile | 3 +- usr/include/arch/arm64/klibc/archconfig.h | 17 +++++++++++ usr/include/arch/arm64/klibc/archsetjmp.h | 22 +++++++++++++++ usr/include/arch/arm64/klibc/archsignal.h | 14 +++++++++ usr/include/arch/arm64/klibc/archstat.h | 29 +++++++++++++++++++ usr/include/arch/arm64/klibc/asmmacros.h | 11 ++++++++ usr/klibc/README.klibc | 1 + usr/klibc/SYSCALLS.def | 2 +- usr/klibc/arch/arm64/Kbuild | 7 +++++ usr/klibc/arch/arm64/MCONFIG | 23 +++++++++++++++ usr/klibc/arch/arm64/crt0.S | 19 +++++++++++++ usr/klibc/arch/arm64/setjmp.S | 47 +++++++++++++++++++++++++++++++ usr/klibc/arch/arm64/syscall.S | 25 ++++++++++++++++ usr/klibc/arch/arm64/sysstub.ph | 25 ++++++++++++++++ usr/klibc/arch/arm64/vfork.S | 34 ++++++++++++++++++++++ 15 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 usr/include/arch/arm64/klibc/archconfig.h create mode 100644 usr/include/arch/arm64/klibc/archsetjmp.h create mode 100644 usr/include/arch/arm64/klibc/archsignal.h create mode 100644 usr/include/arch/arm64/klibc/archstat.h create mode 100644 usr/include/arch/arm64/klibc/asmmacros.h create mode 100644 usr/klibc/arch/arm64/Kbuild create mode 100644 usr/klibc/arch/arm64/MCONFIG create mode 100644 usr/klibc/arch/arm64/crt0.S create mode 100644 usr/klibc/arch/arm64/setjmp.S create mode 100644 usr/klibc/arch/arm64/syscall.S create mode 100644 usr/klibc/arch/arm64/sysstub.ph create mode 100644 usr/klibc/arch/arm64/vfork.S