[klibc] [klibc:master] arm64: Add arm64 support

klibc-bot for Steve Capper steve.capper at linaro.org
Mon Nov 11 19:48:04 PST 2013


Commit-ID:  e4a2c914446ba907c5aaccf6ae1d089a09d21df7
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=e4a2c914446ba907c5aaccf6ae1d089a09d21df7
Author:     Steve Capper <steve.capper at linaro.org>
AuthorDate: Mon, 11 Nov 2013 17:04:12 +0000
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Mon, 11 Nov 2013 19:31:31 -0800

[klibc] arm64: Add arm64 support

Based on work by Neil Williams (codehelp at debian.org) and Anil Singhar
(anil.singhar at linaro.org), this patch adds arm64 support.

Originally-by: Neil Williams <codehelp at debian.org>
Originally-by: Anil Singhar <anil.singhar at linaro.org>
Signed-off-by: Steve Capper <steve.capper at linaro.org>
Signed-off-by: H. Peter Anvin <hpa at zytor.com>

---
 Makefile                                           |  3 +-
 usr/include/arch/{sh => arm64}/klibc/archconfig.h  |  4 +-
 usr/include/arch/arm64/klibc/archsetjmp.h          | 22 ++++++++++
 .../arch/{m32r => arm64}/klibc/archsignal.h        |  2 +-
 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/{parisc => arm64}/Kbuild            |  5 +--
 usr/klibc/arch/{sparc64 => arm64}/MCONFIG          | 18 +++++----
 usr/klibc/arch/{arm => arm64}/crt0.S               | 14 +++----
 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, 218 insertions(+), 24 deletions(-)

diff --git a/Makefile b/Makefile
index 0a3ee69..a7da622 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/sh/klibc/archconfig.h b/usr/include/arch/arm64/klibc/archconfig.h
similarity index 72%
copy from usr/include/arch/sh/klibc/archconfig.h
copy to usr/include/arch/arm64/klibc/archconfig.h
index 923c563..5e2004b 100644
--- a/usr/include/arch/sh/klibc/archconfig.h
+++ b/usr/include/arch/arm64/klibc/archconfig.h
@@ -1,5 +1,5 @@
 /*
- * include/arch/sh/klibc/archconfig.h
+ * include/arch/arm64/klibc/archconfig.h
  *
  * See include/klibc/sysconfig.h for the options that can be set in
  * this file.
@@ -11,5 +11,7 @@
 
 /* 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 0000000..edc3312
--- /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/m32r/klibc/archsignal.h b/usr/include/arch/arm64/klibc/archsignal.h
similarity index 82%
copy from usr/include/arch/m32r/klibc/archsignal.h
copy to usr/include/arch/arm64/klibc/archsignal.h
index b753026..94e6bc8 100644
--- a/usr/include/arch/m32r/klibc/archsignal.h
+++ b/usr/include/arch/arm64/klibc/archsignal.h
@@ -1,5 +1,5 @@
 /*
- * arch/m32r/include/klibc/archsignal.h
+ * arch/arm64/include/klibc/archsignal.h
  *
  * Architecture-specific signal definitions
  *
diff --git a/usr/include/arch/arm64/klibc/archstat.h b/usr/include/arch/arm64/klibc/archstat.h
new file mode 100644
index 0000000..a1a3e79
--- /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 0000000..c298f66
--- /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 7de5fea..c72ae47 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 12f57ac..41cfa17 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 at forkish();
 #endif
 #if _KLIBC_REAL_VFORK
diff --git a/usr/klibc/arch/parisc/Kbuild b/usr/klibc/arch/arm64/Kbuild
similarity index 74%
copy from usr/klibc/arch/parisc/Kbuild
copy to usr/klibc/arch/arm64/Kbuild
index 57ca5c2..f8643b5 100644
--- a/usr/klibc/arch/parisc/Kbuild
+++ b/usr/klibc/arch/arm64/Kbuild
@@ -1,8 +1,7 @@
-#
-# klibc files for parisc
+
+# klibc files for arm64
 #
 
 klib-y := setjmp.o syscall.o vfork.o
-
 always  := crt0.o
 targets := crt0.o
diff --git a/usr/klibc/arch/sparc64/MCONFIG b/usr/klibc/arch/arm64/MCONFIG
similarity index 51%
copy from usr/klibc/arch/sparc64/MCONFIG
copy to usr/klibc/arch/arm64/MCONFIG
index bd6f004..82664a7 100644
--- a/usr/klibc/arch/sparc64/MCONFIG
+++ b/usr/klibc/arch/arm64/MCONFIG
@@ -1,21 +1,23 @@
 # -*- makefile -*-
 #
-# arch/sparc64/MCONFIG
+# arch/arm64/MCONFIG
 #
 # Special rules for this architecture.  Note that this is actually
 # included from the main Makefile, and that pathnames should be
 # accordingly.
 #
 
-KLIBCARCHREQFLAGS = -m64 -mptr64 -D__sparc64__
-KLIBCOPTFLAGS     += -Os
-KLIBCBITSIZE      = 64
+CPU_ARCH ?= armv8-a
+CPU_TUNE ?= generic
 
-KLIBCLDFLAGS      = -m elf64_sparc
+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
-# Normal binaries start at 1 MB; the linker wants 1 MB alignment,
-# and call instructions have a 30-bit signed offset, << 2.
-KLIBCSHAREDFLAGS	= -Ttext 0x80000200
+
+# 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/arm/crt0.S b/usr/klibc/arch/arm64/crt0.S
similarity index 62%
copy from usr/klibc/arch/arm/crt0.S
copy to usr/klibc/arch/arm64/crt0.S
index 1e81f8e..0b2dd32 100644
--- a/usr/klibc/arch/arm/crt0.S
+++ b/usr/klibc/arch/arm64/crt0.S
@@ -1,5 +1,5 @@
 #
-# arch/arm/crt0.S
+# arch/arm64/crt0.S
 #
 # void _start(void)
 # {
@@ -8,16 +8,12 @@
 #
 
 	.text
-	.balign 4
+	.balign 8
 	.type _start,#function
 	.globl _start
 
-#ifdef __thumb__
-	.thumb_func
-#endif
-
-_start:	mov	r0, sp
-	mov	r1, #0
+_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 0000000..13ab99d
--- /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 0000000..3ce91fb
--- /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 0000000..47cbfd9
--- /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 0000000..494326c
--- /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


More information about the klibc mailing list