klibc-bot for Steve Capper
2013-Nov-12 03:48 UTC
[klibc] [klibc:master] arm64: Add arm64 support
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