Index: sys/arm64/arm64/elf_machdep.c =================================================================== --- sys/arm64/arm64/elf_machdep.c +++ sys/arm64/arm64/elf_machdep.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014 The FreeBSD Foundation. + * Copyright (c) 2014, 2015 The FreeBSD Foundation. * Copyright (c) 2014 Andrew Turner. * Copyright (c) 2001 Jake Burkholder. * Copyright (c) 2000 Eduardo Horvath. @@ -12,6 +12,9 @@ * This software was developed by Andrew Turner under * sponsorship from the FreeBSD Foundation. * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -132,12 +135,66 @@ } +static int +elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, int local, elf_lookup_fn lookup) +{ + Elf_Addr *where, addr, addend; + Elf_Word rtype, symidx; + const Elf_Rel *rel; + const Elf_Rela *rela; + int error; + + switch (type) { + case ELF_RELOC_REL: + rel = (const Elf_Rel *)data; + where = (Elf_Addr *) (relocbase + rel->r_offset); + addend = *where; + rtype = ELF_R_TYPE(rel->r_info); + symidx = ELF_R_SYM(rel->r_info); + break; + case ELF_RELOC_RELA: + rela = (const Elf_Rela *)data; + where = (Elf_Addr *) (relocbase + rela->r_offset); + addend = rela->r_addend; + rtype = ELF_R_TYPE(rela->r_info); + symidx = ELF_R_SYM(rela->r_info); + break; + default: + panic("unknown reloc type %d\n", type); + } + + if (local) { + if (rtype == R_AARCH64_RELATIVE) + *where = elf_relocaddr(lf, relocbase + addend); + return (0); + } + + switch (rtype) { + case R_AARCH64_NONE: + case R_AARCH64_RELATIVE: + break; + case R_AARCH64_ABS64: + case R_AARCH64_GLOB_DAT: + case R_AARCH64_JUMP_SLOT: + error = lookup(lf, symidx, 1, &addr); + if (error != 0) + return (-1); + *where = addr + addend; + break; + default: + printf("kldload: unexpected relocation type %d\n", rtype); + return (-1); + } + return (0); +} + int elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, - int type, elf_lookup_fn lookup __unused) + int type, elf_lookup_fn lookup) { - panic("ARM64TODO: elf_reloc_local"); + return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); } /* Process one elf relocation with addend. */ @@ -146,13 +203,15 @@ elf_lookup_fn lookup) { - panic("ARM64TODO: elf_reloc"); + return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); } int -elf_cpu_load_file(linker_file_t lf __unused) +elf_cpu_load_file(linker_file_t lf) { + if (lf->id != 1) + cpu_icache_sync_range((vm_offset_t)lf->address, lf->size); return (0); } Index: sys/arm64/conf/GENERIC =================================================================== --- sys/arm64/conf/GENERIC +++ sys/arm64/conf/GENERIC @@ -22,7 +22,6 @@ ident GENERIC makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols -makeoptions NO_MODULES=1 # We don't yet support modules on arm64 options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption Index: sys/conf/Makefile.arm64 =================================================================== --- sys/conf/Makefile.arm64 +++ sys/conf/Makefile.arm64 @@ -27,12 +27,6 @@ INCLUDES+= -I$S/contrib/libfdt -# We generally don't want fpu instructions in the kernel. -CFLAGS += -mgeneral-regs-only - -# Reserve x18 for pcpu data -CFLAGS += -ffixed-x18 - .if !empty(DDB_ENABLED) CFLAGS += -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer .endif Index: sys/conf/kern.mk =================================================================== --- sys/conf/kern.mk +++ sys/conf/kern.mk @@ -94,6 +94,13 @@ INLINE_LIMIT?= 8000 .endif +.if ${MACHINE_CPUARCH} == "aarch64" +# We generally don't want fpu instructions in the kernel. +CFLAGS += -mgeneral-regs-only +# Reserve x18 for pcpu data +CFLAGS += -ffixed-x18 +.endif + # # For sparc64 we want the medany code model so modules may be located # anywhere in the 64-bit address space. We also tell GCC to use floating Index: sys/conf/kern.post.mk =================================================================== --- sys/conf/kern.post.mk +++ sys/conf/kern.post.mk @@ -212,7 +212,7 @@ mv .newdep .depend _ILINKS= machine -.if ${MACHINE} != ${MACHINE_CPUARCH} +.if ${MACHINE} != ${MACHINE_CPUARCH} && ${MACHINE} != "arm64" _ILINKS+= ${MACHINE_CPUARCH} .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" Index: sys/conf/kmod.mk =================================================================== --- sys/conf/kmod.mk +++ sys/conf/kmod.mk @@ -113,6 +113,10 @@ CFLAGS+= -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer .endif +.if ${MACHINE_CPUARCH} == "aarch64" +CFLAGS+= -fPIC +.endif + # Temporary workaround for PR 196407, which contains the fascinating details. # Don't allow clang to use fpu instructions or registers in kernel modules. .if ${MACHINE_CPUARCH} == arm @@ -182,7 +186,17 @@ .if ${__KLD_SHARED} == yes ${FULLPROG}: ${KMOD}.kld +.if ${MACHINE_CPUARCH} != "aarch64" ${LD} -Bshareable ${_LDFLAGS} -o ${.TARGET} ${KMOD}.kld +.else +#XXXKIB Relocatable linking in aarch64 ld from binutils 2.25.1 does +# not work. The linker corrupts the references to the external +# symbols which are defined by other object in the linking set +# and should therefore loose the GOT entry. The problem seems +# to be fixed in the binutils-gdb git HEAD as of 2015-10-04. Hack +# below allows to get partially functioning modules for now. + ${LD} -Bshareable ${_LDFLAGS} -o ${.TARGET} ${OBJS} +.endif .if !defined(DEBUG_FLAGS) ${OBJCOPY} --strip-debug ${.TARGET} .endif @@ -220,7 +234,7 @@ .endif _ILINKS=machine -.if ${MACHINE} != ${MACHINE_CPUARCH} +.if ${MACHINE} != ${MACHINE_CPUARCH} && ${MACHINE} != "arm64" _ILINKS+=${MACHINE_CPUARCH} .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" Index: sys/dev/sym/sym_hipd.c =================================================================== --- sys/dev/sym/sym_hipd.c +++ sys/dev/sym/sym_hipd.c @@ -136,6 +136,8 @@ #define MEMORY_BARRIER() __asm__ volatile("membar #Sync" : : : "memory") #elif defined __arm__ #define MEMORY_BARRIER() dmb() +#elif defined __aarch64__ +#define MEMORY_BARRIER() dmb(sy) #else #error "Not supported platform" #endif Index: sys/modules/Makefile =================================================================== --- sys/modules/Makefile +++ sys/modules/Makefile @@ -479,8 +479,8 @@ _cxgbe= cxgbe .endif -.if ${MACHINE_CPUARCH} != "arm" && ${MACHINE_CPUARCH} != "mips" && \ - ${MACHINE_CPUARCH} != "powerpc" +.if ${MACHINE_CPUARCH} != "aarch64" && ${MACHINE_CPUARCH} != "arm" && \ + ${MACHINE_CPUARCH} != "mips" && ${MACHINE_CPUARCH} != "powerpc" _syscons= syscons _vpo= vpo .endif