diff --git a/repos/base/etc/tools.conf b/repos/base/etc/tools.conf index c3278835a..a01f219d6 100644 --- a/repos/base/etc/tools.conf +++ b/repos/base/etc/tools.conf @@ -30,6 +30,9 @@ endif ifeq ($(filter-out $(SPECS),riscv),) CROSS_DEV_PREFIX ?= /usr/local/genode-gcc/bin/genode-riscv- endif +ifeq ($(filter-out $(SPECS),arm_64),) +CROSS_DEV_PREFIX ?= /usr/local/genode-gcc/bin/genode-aarch64- +endif # # We use libsupc++ from g++ version 3 because diff --git a/repos/base/include/spec/arm_64/cpu/atomic.h b/repos/base/include/spec/arm_64/cpu/atomic.h new file mode 100644 index 000000000..815f63000 --- /dev/null +++ b/repos/base/include/spec/arm_64/cpu/atomic.h @@ -0,0 +1,56 @@ +/* + * \brief Atomic operations for ARM 64-bit. + * \author Stefan Kalkowski + * \date 2019-03-25 + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _INCLUDE__SPEC__ARM_64__CPU__ATOMIC_H_ +#define _INCLUDE__SPEC__ARM_64__CPU__ATOMIC_H_ + +#include + +namespace Genode { + + /** + * Atomic compare and exchange + * + * This function compares the value at dest with cmp_val. + * If both values are equal, dest is set to new_val. If + * both values are different, the value at dest remains + * unchanged. + * + * Note, that cmpxchg() represents a memory barrier. + * + * \return 1 if the value was successfully changed to new_val, + * 0 if cmp_val and the value at dest differ. + */ + inline int cmpxchg(volatile int *dest, int cmp_val, int new_val) + { + int fail, old_val = 0; + + do { + asm volatile( + "ldxr %w1, %2 \n" + "mov %w0, #0 \n" + "cmp %w1, %w3 \n" + "b.ne 1f \n" + "stxr %w0, %w4, %2 \n" + "1: \n" + : "=&r" (fail), "=&r" (old_val), "+Q" (*dest) + : "r" (cmp_val), "r" (new_val) + : "cc"); + } while (fail); + + Genode::memory_barrier(); + return (old_val != cmp_val) ? 0 : 1; + } +} + +#endif /* _INCLUDE__SPEC__ARM_64__CPU__ATOMIC_H_ */ diff --git a/repos/base/include/spec/arm_64/cpu/consts.h b/repos/base/include/spec/arm_64/cpu/consts.h new file mode 100644 index 000000000..18fe03b14 --- /dev/null +++ b/repos/base/include/spec/arm_64/cpu/consts.h @@ -0,0 +1,33 @@ +/* + * \brief Constants definitions for ARM 64-bit. + * \author Stefan Kalkowski + * \date 2019-03-25 + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _INCLUDE__SPEC__ARM_64__CPU__CONSTS_H_ +#define _INCLUDE__SPEC__ARM_64__CPU__CONSTS_H_ + +#include + +namespace Abi { + + /* + * On ARM we align the stack top to 16-byte. + */ + inline Genode::addr_t stack_align(Genode::addr_t addr) { + return (addr & ~0xf); } + + /** + * Do ABI specific initialization to a freshly created stack + */ + inline void init_stack(Genode::addr_t) { } +} + +#endif /* _INCLUDE__SPEC__ARM_64__CPU__CONSTS_H_ */ diff --git a/repos/base/include/spec/arm_64/cpu/cpu_state.h b/repos/base/include/spec/arm_64/cpu/cpu_state.h new file mode 100644 index 000000000..b6b9d5b74 --- /dev/null +++ b/repos/base/include/spec/arm_64/cpu/cpu_state.h @@ -0,0 +1,31 @@ +/* + * \brief CPU state + * \author Stefan Kalkowski + * \date 2019-03-25 + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _INCLUDE__SPEC__ARM_64__CPU__CPU_STATE_H_ +#define _INCLUDE__SPEC__ARM_64__CPU__CPU_STATE_H_ + +/* Genode includes */ +#include + +namespace Genode { struct Cpu_state; } + + +struct Genode::Cpu_state +{ + addr_t r[31] { 0 }; /* general purpose register 0...30 */ + addr_t sp { 0 }; /* stack pointer */ + addr_t ip { 0 }; /* instruction pointer */ +}; + +#endif /* _INCLUDE__SPEC__ARM_64__CPU__CPU_STATE_H_ */ + diff --git a/repos/base/include/spec/arm_64/cpu/memory_barrier.h b/repos/base/include/spec/arm_64/cpu/memory_barrier.h new file mode 100644 index 000000000..0bd3ccfdf --- /dev/null +++ b/repos/base/include/spec/arm_64/cpu/memory_barrier.h @@ -0,0 +1,34 @@ +/* + * \brief Memory barrier + * \author Stefan Kalkowski + * \date 2019-03-25 + * + * The memory barrier prevents memory accesses from being reordered in such a + * way that accesses to the guarded resource get outside the guarded stage. As + * cmpxchg() defines the start of the guarded stage it also represents an + * effective memory barrier. + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _INCLUDE__SPEC__ARM_64__CPU__MEMORY_BARRIER_H_ +#define _INCLUDE__SPEC__ARM_64__CPU__MEMORY_BARRIER_H_ + +namespace Genode { + + static inline void memory_barrier() + { + /* + * Be conversative for the time-being and synchronize with all level + */ + asm volatile ("dsb #15" ::: "memory"); + } +} + +#endif /* _INCLUDE__SPEC__ARM_64__CPU__MEMORY_BARRIER_H_ */ + diff --git a/repos/base/include/spec/arm_64/cpu/string.h b/repos/base/include/spec/arm_64/cpu/string.h new file mode 100644 index 000000000..2c5050e41 --- /dev/null +++ b/repos/base/include/spec/arm_64/cpu/string.h @@ -0,0 +1,31 @@ +/* + * \brief CPU-specific memcpy + * \author Stefan Kalkowski + * \date 2012-08-02 + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _INCLUDE__SPEC__ARM_64__CPU__STRING_H_ +#define _INCLUDE__SPEC__ARM_64__CPU__STRING_H_ + +namespace Genode { + + /** + * Copy memory block + * + * \param dst destination memory block + * \param src source memory block + * \param size number of bytes to copy + * + * \return number of bytes not copied + */ + inline size_t memcpy_cpu(void *, const void *, size_t size) { return size; } +} + +#endif /* _INCLUDE__SPEC__ARM_64__CPU__STRING_H_ */ diff --git a/repos/base/include/spec/arm_64/trace/timestamp.h b/repos/base/include/spec/arm_64/trace/timestamp.h new file mode 100644 index 000000000..972debde8 --- /dev/null +++ b/repos/base/include/spec/arm_64/trace/timestamp.h @@ -0,0 +1,29 @@ +/* + * \brief Trace timestamp + * \author Stefan Kalkowski + * \date 2019-03-25 + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _INCLUDE__SPEC__ARM_64__TRACE__TIMESTAMP_H_ +#define _INCLUDE__SPEC__ARM_64__TRACE__TIMESTAMP_H_ + +#include + +namespace Genode { namespace Trace { + + typedef uint32_t Timestamp; + + inline Timestamp timestamp() + { + return 0; + } +} } + +#endif /* _INCLUDE__SPEC__ARM_64__TRACE__TIMESTAMP_H_ */ diff --git a/repos/base/lib/mk/spec/arm_64/ld-platform.inc b/repos/base/lib/mk/spec/arm_64/ld-platform.inc new file mode 100644 index 000000000..5cf227f1e --- /dev/null +++ b/repos/base/lib/mk/spec/arm_64/ld-platform.inc @@ -0,0 +1,4 @@ +include $(BASE_DIR)/lib/mk/ld-platform.inc + +INC_DIR += $(DIR)/spec/arm_64 +vpath %.s $(DIR)/spec/arm_64 diff --git a/repos/base/mk/spec/arm_v8a.mk b/repos/base/mk/spec/arm_v8a.mk new file mode 100644 index 000000000..6f93398c1 --- /dev/null +++ b/repos/base/mk/spec/arm_v8a.mk @@ -0,0 +1,7 @@ +SPECS += arm_v8 arm_64 64bit +REP_INC_DIR += include/spec/arm_v8 +REP_INC_DIR += include/spec/arm_64 + +CC_MARCH ?= -march=armv8-a + +include $(BASE_DIR)/mk/spec/64bit.mk diff --git a/repos/base/src/lib/ldso/spec/arm_64/jmp_slot.s b/repos/base/src/lib/ldso/spec/arm_64/jmp_slot.s new file mode 100644 index 000000000..9dc186e38 --- /dev/null +++ b/repos/base/src/lib/ldso/spec/arm_64/jmp_slot.s @@ -0,0 +1,19 @@ +/** + * \brief Jump slot entry code for ARM 64-bit platforms + * \author Stefan Kalkowski + * \date 2019-03-27 + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +.text +.globl _jmp_slot +.type _jmp_slot,%function + +_jmp_slot: + 1: b 1b diff --git a/repos/base/src/lib/ldso/spec/arm_64/relocation.h b/repos/base/src/lib/ldso/spec/arm_64/relocation.h new file mode 100644 index 000000000..142c4fb29 --- /dev/null +++ b/repos/base/src/lib/ldso/spec/arm_64/relocation.h @@ -0,0 +1,69 @@ +/** + * \brief ARM 64-bit specific relocations + * \author Stefan Kalkowski + * \date 2014-10-26 + */ + +/* + * Copyright (C) 2014-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _LIB__LDSO__SPEC__ARM_64__RELOCATION_H_ +#define _LIB__LDSO__SPEC__ARM_64__RELOCATION_H_ + +#include +#include + +namespace Linker { + +/** + * Relocation types + */ + enum Reloc_types { + R_64 = 1, /* add 64 bit symbol value. */ + R_COPY = 5, + R_GLOB_DAT = 6, /* GOT entry to data address */ + R_JMPSLOT = 7, /* jump slot */ + R_RELATIVE = 8, /* add load addr of shared object */ + }; + + class Reloc_non_plt; + + typedef Reloc_plt_generic Reloc_plt; + typedef Reloc_jmpslot_generic Reloc_jmpslot; + typedef Reloc_bind_now_generic Reloc_bind_now; +}; + +class Linker::Reloc_non_plt : public Reloc_non_plt_generic +{ + private: + + void _relative(Elf::Rela const *, Elf::Addr *) + { + error("not implemented yet"); + } + + void _glob_dat_64(Elf::Rela const *, Elf::Addr *, bool) + { + error("not implemented yet"); + } + + public: + + Reloc_non_plt(Dependency const &dep, Elf::Rela const *, unsigned long, bool) + : Reloc_non_plt_generic(dep) + { + error("not implemented yet"); + } + + Reloc_non_plt(Dependency const &dep, Elf::Rel const *, unsigned long, bool) + : Reloc_non_plt_generic(dep) + { + error("not implemented yet"); + } +}; + +#endif /* _LIB__LDSO__SPEC__ARM_64__RELOCATION_H_ */ diff --git a/repos/base/src/lib/startup/spec/arm_64/crt0.s b/repos/base/src/lib/startup/spec/arm_64/crt0.s new file mode 100644 index 000000000..d0f1a238f --- /dev/null +++ b/repos/base/src/lib/startup/spec/arm_64/crt0.s @@ -0,0 +1,76 @@ +/** + * \brief Startup code for Genode applications on ARM 64-bit + * \author Stefan Kalkowski + * \date 2019-03-26 + */ + +/* + * Copyright (C) 2019 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + + +/************************** + ** .text (program code) ** + **************************/ + +.section ".text.crt0" + + /* program entry-point */ + .global _start + _start: + .global _start_initial_stack + _start_initial_stack: + + /* make initial value of some registers available to higher-level code */ + ldr x4, =__initial_sp + mov x5, sp + str x5, [x4] + ldr x4, =__initial_x0 + str x0, [x4] + + /* + * Install initial temporary environment that is replaced later by the + * environment that init_main_thread creates. + */ + ldr x4, =_stack_high + mov sp, x4 + + /* if this is the dynamic linker, init_rtld relocates the linker */ + bl init_rtld + + /* create proper environment for main thread */ + bl init_main_thread + + /* apply environment that was created by init_main_thread */ + ldr x4, =init_main_thread_result + ldr x4, [x4] + mov sp, x4 + + /* jump into init C code instead of calling it as it should never return */ + b _main + + +/********************************* + ** .bss (non-initialized data) ** + *********************************/ + +.section ".bss" + + /* stack of the temporary initial environment */ + .p2align 8 + .global __initial_stack_base + __initial_stack_base: + .space 12*1024 + _stack_high: + + /* initial value of the SP register */ + .global __initial_sp + __initial_sp: + .space 8 + /* initial value of the X0 register */ + .global __initial_x0 + __initial_x0: + .space 8 diff --git a/tool/builddir/build.conf/run_arm_v8 b/tool/builddir/build.conf/run_arm_v8 new file mode 100644 index 000000000..ef7e085a5 --- /dev/null +++ b/tool/builddir/build.conf/run_arm_v8 @@ -0,0 +1,27 @@ +# local variable for run-tool arguments used for running scenarios in Qemu +QEMU_RUN_OPT := --include power_on/qemu --include log/qemu + +# kernel to use (hw, foc, or sel4) +#KERNEL ?= hw + +# board to use (rpi3) +#BOARD ?= rpi3 + +# local varible for run-tool arguments that depend on the used kernel +KERNEL_RUN_OPT(hw) := $(QEMU_RUN_OPT) +KERNEL_RUN_OPT(foc) := $(QEMU_RUN_OPT) +KERNEL_RUN_OPT(sel4) := $(QEMU_RUN_OPT) + +## +## Qemu arguments, effective when using the run tool's 'power_on/qemu' back end +## + +# enable GDB stub +#QEMU_OPT += -s + +# use time-tested graphics backend +QEMU_OPT += -display sdl + +# add kernel-specific Qemu arguments +QEMU_OPT += $(QEMU_OPT(${KERNEL})) + diff --git a/tool/create_builddir b/tool/create_builddir index 3a7351116..5233ebbea 100755 --- a/tool/create_builddir +++ b/tool/create_builddir @@ -10,7 +10,7 @@ MAKEOVERRIDES = PLATFORM = $(MAKECMDGOALS) -PLATFORMS = arm_v6 arm_v7a riscv x86_32 x86_64 linux +PLATFORMS = arm_v6 arm_v7a arm_v8a riscv x86_32 x86_64 linux PLATFORMS_DEPR = arndale imx53_qsb imx53_qsb_tz imx6q_sabrelite imx7d_sabre \ nit6_solox odroid_x2 odroid_xu panda pbxa9 riscv_spike rpi \ @@ -118,6 +118,7 @@ BUILD_CONF_ARM_V6 := run_arm_v6 run_boot_dir repos BUILD_CONF_ARM_V7 := run_arm_v7 run_boot_dir repos BUILD_CONF(arm_v6) := $(BUILD_CONF_ARM_V6) BUILD_CONF(arm_v7a) := $(BUILD_CONF_ARM_V7) +BUILD_CONF(arm_v8a) := run_arm_v8 run_boot_dir repos BUILD_CONF(riscv) := run_riscv run_boot_dir repos BUILD_CONF(x86_32) := run_x86_32 $(BUILD_CONF_X86) BUILD_CONF(x86_64) := run_x86_64 $(BUILD_CONF_X86) @@ -186,6 +187,7 @@ HOST_SPEC_ARCH := ${SPEC_ARCH(${UNAME_MACHINE})} SPECS(arm_v6) := arm_v6 SPECS(arm_v7a) := arm_v7a +SPECS(arm_v8a) := arm_v8a SPECS(riscv) := riscv SPECS(x86_32) := x86_32 SPECS(x86_64) := x86_64