aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Capper <steve.capper@linaro.org>2013-11-11 17:04:12 +0000
committerH. Peter Anvin <hpa@zytor.com>2013-11-11 19:31:31 -0800
commite4a2c914446ba907c5aaccf6ae1d089a09d21df7 (patch)
tree93fd680c0a74bd74eda1e33a862000aee2fec667
parent8858e8319655ef38398e0833b71d65b0e620a061 (diff)
downloadklibc-e4a2c914446ba907c5aaccf6ae1d089a09d21df7.tar.gz
[klibc] arm64: Add arm64 support
Based on work by Neil Williams (codehelp@debian.org) and Anil Singhar (anil.singhar@linaro.org), this patch adds 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> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--Makefile3
-rw-r--r--usr/include/arch/arm64/klibc/archconfig.h17
-rw-r--r--usr/include/arch/arm64/klibc/archsetjmp.h22
-rw-r--r--usr/include/arch/arm64/klibc/archsignal.h14
-rw-r--r--usr/include/arch/arm64/klibc/archstat.h29
-rw-r--r--usr/include/arch/arm64/klibc/asmmacros.h11
-rw-r--r--usr/klibc/README.klibc1
-rw-r--r--usr/klibc/SYSCALLS.def2
-rw-r--r--usr/klibc/arch/arm64/Kbuild7
-rw-r--r--usr/klibc/arch/arm64/MCONFIG23
-rw-r--r--usr/klibc/arch/arm64/crt0.S19
-rw-r--r--usr/klibc/arch/arm64/setjmp.S47
-rw-r--r--usr/klibc/arch/arm64/syscall.S25
-rw-r--r--usr/klibc/arch/arm64/sysstub.ph25
-rw-r--r--usr/klibc/arch/arm64/vfork.S34
15 files changed, 277 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 0a3ee69ebd37b5..a7da622c83a37f 100644
--- a/Makefile
+++ b/Makefile
@@ -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/)
diff --git a/usr/include/arch/arm64/klibc/archconfig.h b/usr/include/arch/arm64/klibc/archconfig.h
new file mode 100644
index 00000000000000..5e2004bd820643
--- /dev/null
+++ b/usr/include/arch/arm64/klibc/archconfig.h
@@ -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 */
diff --git a/usr/include/arch/arm64/klibc/archsetjmp.h b/usr/include/arch/arm64/klibc/archsetjmp.h
new file mode 100644
index 00000000000000..edc3312f7315f2
--- /dev/null
+++ b/usr/include/arch/arm64/klibc/archsetjmp.h
@@ -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 */
diff --git a/usr/include/arch/arm64/klibc/archsignal.h b/usr/include/arch/arm64/klibc/archsignal.h
new file mode 100644
index 00000000000000..94e6bc8ef2e4ba
--- /dev/null
+++ b/usr/include/arch/arm64/klibc/archsignal.h
@@ -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
diff --git a/usr/include/arch/arm64/klibc/archstat.h b/usr/include/arch/arm64/klibc/archstat.h
new file mode 100644
index 00000000000000..a1a3e7906570ab
--- /dev/null
+++ b/usr/include/arch/arm64/klibc/archstat.h
@@ -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
diff --git a/usr/include/arch/arm64/klibc/asmmacros.h b/usr/include/arch/arm64/klibc/asmmacros.h
new file mode 100644
index 00000000000000..c298f6601e603d
--- /dev/null
+++ b/usr/include/arch/arm64/klibc/asmmacros.h
@@ -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 */
diff --git a/usr/klibc/README.klibc b/usr/klibc/README.klibc
index 7de5fea52fce10..c72ae476bb672c 100644
--- a/usr/klibc/README.klibc
+++ b/usr/klibc/README.klibc
@@ -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
diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def
index 12f57ac162c536..41cfa171b0e416 100644
--- a/usr/klibc/SYSCALLS.def
+++ b/usr/klibc/SYSCALLS.def
@@ -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
diff --git a/usr/klibc/arch/arm64/Kbuild b/usr/klibc/arch/arm64/Kbuild
new file mode 100644
index 00000000000000..f8643b50139671
--- /dev/null
+++ b/usr/klibc/arch/arm64/Kbuild
@@ -0,0 +1,7 @@
+
+# klibc files for arm64
+#
+
+klib-y := setjmp.o syscall.o vfork.o
+always := crt0.o
+targets := crt0.o
diff --git a/usr/klibc/arch/arm64/MCONFIG b/usr/klibc/arch/arm64/MCONFIG
new file mode 100644
index 00000000000000..82664a7b7f5ed3
--- /dev/null
+++ b/usr/klibc/arch/arm64/MCONFIG
@@ -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
diff --git a/usr/klibc/arch/arm64/crt0.S b/usr/klibc/arch/arm64/crt0.S
new file mode 100644
index 00000000000000..0b2dd32b6d5489
--- /dev/null
+++ b/usr/klibc/arch/arm64/crt0.S
@@ -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
diff --git a/usr/klibc/arch/arm64/setjmp.S b/usr/klibc/arch/arm64/setjmp.S
new file mode 100644
index 00000000000000..13ab99d4f03376
--- /dev/null
+++ b/usr/klibc/arch/arm64/setjmp.S
@@ -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
diff --git a/usr/klibc/arch/arm64/syscall.S b/usr/klibc/arch/arm64/syscall.S
new file mode 100644
index 00000000000000..3ce91fb77aa5fa
--- /dev/null
+++ b/usr/klibc/arch/arm64/syscall.S
@@ -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
diff --git a/usr/klibc/arch/arm64/sysstub.ph b/usr/klibc/arch/arm64/sysstub.ph
new file mode 100644
index 00000000000000..47cbfd900bb16c
--- /dev/null
+++ b/usr/klibc/arch/arm64/sysstub.ph
@@ -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;
diff --git a/usr/klibc/arch/arm64/vfork.S b/usr/klibc/arch/arm64/vfork.S
new file mode 100644
index 00000000000000..494326c3274c48
--- /dev/null
+++ b/usr/klibc/arch/arm64/vfork.S
@@ -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