base: add initial support for ARM 64-bit

Ref #3260
This commit is contained in:
Stefan Kalkowski 2019-03-29 10:40:29 +01:00 committed by Christian Helmuth
parent c98597a2c0
commit 71a48c0a26
14 changed files with 422 additions and 1 deletions

View File

@ -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

View File

@ -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 <cpu/memory_barrier.h>
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_ */

View File

@ -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 <base/stdint.h>
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_ */

View File

@ -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 <base/stdint.h>
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_ */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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 <base/fixed_stdint.h>
namespace Genode { namespace Trace {
typedef uint32_t Timestamp;
inline Timestamp timestamp()
{
return 0;
}
} }
#endif /* _INCLUDE__SPEC__ARM_64__TRACE__TIMESTAMP_H_ */

View File

@ -0,0 +1,4 @@
include $(BASE_DIR)/lib/mk/ld-platform.inc
INC_DIR += $(DIR)/spec/arm_64
vpath %.s $(DIR)/spec/arm_64

View File

@ -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

View File

@ -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

View File

@ -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 <relocation_generic.h>
#include <dynamic_generic.h>
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<Elf::Rela, DT_RELA, R_JMPSLOT> Reloc_plt;
typedef Reloc_jmpslot_generic<Elf::Rela, DT_RELA, false> Reloc_jmpslot;
typedef Reloc_bind_now_generic<Elf::Rela, DT_RELA> 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_ */

View File

@ -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

View File

@ -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}))

View File

@ -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