diff --git a/repos/base-hw/lib/mk/arm/core.inc b/repos/base-hw/lib/mk/arm/core.inc index a0fc63e85..a6c3899e5 100644 --- a/repos/base-hw/lib/mk/arm/core.inc +++ b/repos/base-hw/lib/mk/arm/core.inc @@ -13,6 +13,7 @@ SRC_CC += spec/arm/kernel/thread.cc SRC_CC += spec/arm/kernel/cpu.cc # add assembly sources +SRC_S += spec/arm/kernel/crt0.s SRC_S += spec/arm/crt0.s # include less specific configuration diff --git a/repos/base-hw/lib/mk/arm_v6/core.inc b/repos/base-hw/lib/mk/arm_v6/core.inc index 81daf9426..47681183b 100644 --- a/repos/base-hw/lib/mk/arm_v6/core.inc +++ b/repos/base-hw/lib/mk/arm_v6/core.inc @@ -11,6 +11,7 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/arm_v6 SRC_CC += spec/arm/cpu.cc SRC_CC += spec/arm/kernel/cpu_context.cc SRC_CC += kernel/vm_thread.cc +SRC_CC += spec/arm_v6/cpu.cc # add assembly sources SRC_S += spec/arm_v6/mode_transition.s diff --git a/repos/base-hw/lib/mk/arm_v7/core.inc b/repos/base-hw/lib/mk/arm_v7/core.inc index 9e765bd33..64d778916 100644 --- a/repos/base-hw/lib/mk/arm_v7/core.inc +++ b/repos/base-hw/lib/mk/arm_v7/core.inc @@ -7,6 +7,9 @@ # add include paths INC_DIR += $(REP_DIR)/src/core/include/spec/arm_v7 +# add C++ sources +SRC_CC += spec/arm_v7/cpu.cc + # add assembly sources SRC_S += spec/arm_v7/mode_transition.s diff --git a/repos/base-hw/lib/mk/core.inc b/repos/base-hw/lib/mk/core.inc index 014c024ff..f86b7e17c 100644 --- a/repos/base-hw/lib/mk/core.inc +++ b/repos/base-hw/lib/mk/core.inc @@ -7,9 +7,6 @@ # add library dependencies LIBS += core-perf_counter -# set entry point of core's first thread -CC_OPT += -DCORE_MAIN=_main - # add library dependencies LIBS += base-common @@ -54,6 +51,7 @@ SRC_CC += kernel/signal_receiver.cc SRC_CC += kernel/irq.cc SRC_CC += kernel/pd.cc SRC_CC += kernel/cpu.cc +SRC_CC += init_main_thread.cc # add assembly sources SRC_S += boot_modules.s diff --git a/repos/base-hw/src/base/thread/bootstrap.cc b/repos/base-hw/src/base/thread/bootstrap.cc index 628d776dd..9ecd09ed7 100644 --- a/repos/base-hw/src/base/thread/bootstrap.cc +++ b/repos/base-hw/src/base/thread/bootstrap.cc @@ -63,12 +63,10 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); } ** Thread_base ** *****************/ -extern Native_utcb* main_thread_utcb(); - Native_utcb * Thread_base::utcb() { if (this) { return &_context->utcb; } - return main_thread_utcb(); + return UTCB_MAIN_THREAD; } diff --git a/repos/base-hw/src/base/thread/start.cc b/repos/base-hw/src/base/thread/start.cc index 7b1cdccc5..03546a833 100644 --- a/repos/base-hw/src/base/thread/start.cc +++ b/repos/base-hw/src/base/thread/start.cc @@ -26,12 +26,6 @@ extern Ram_dataspace_capability _main_thread_utcb_ds; extern Native_thread_id _main_thread_id; -/** - * Return virtual UTCB location of main threads - */ -Native_utcb * main_thread_utcb() { return UTCB_MAIN_THREAD; } - - /***************** ** Thread_base ** *****************/ diff --git a/repos/base-hw/src/core/include/spec/arm/cpu_support.h b/repos/base-hw/src/core/include/spec/arm/cpu_support.h index 100908127..7b1690174 100644 --- a/repos/base-hw/src/core/include/spec/arm/cpu_support.h +++ b/repos/base-hw/src/core/include/spec/arm/cpu_support.h @@ -252,7 +252,7 @@ class Genode::Arm /** * Return value initialized for user execution with trustzone */ - inline static access_t init_user_with_trustzone(); + static access_t init_user_with_trustzone(); /** * Do common initialization on register value 'v' @@ -467,12 +467,12 @@ class Genode::Arm /** * Flush all entries of all data caches */ - inline static void flush_data_caches(); + static void flush_data_caches(); /** * Invalidate all entries of all data caches */ - inline static void invalidate_data_caches(); + static void invalidate_data_caches(); /** * Flush all caches diff --git a/repos/base-hw/src/core/include/spec/arm_v6/cpu.h b/repos/base-hw/src/core/include/spec/arm_v6/cpu.h index 05f76d9d2..87ccba4df 100644 --- a/repos/base-hw/src/core/include/spec/arm_v6/cpu.h +++ b/repos/base-hw/src/core/include/spec/arm_v6/cpu.h @@ -160,6 +160,7 @@ class Genode::Cpu : public Arm * adds translations solely before MMU and caches are enabled. */ if (is_user()) Kernel::update_data_region(addr, size); + else flush_data_caches(); } /** @@ -182,16 +183,4 @@ class Genode::Cpu : public Arm static void invalidate_control_flow_predictions() { /* FIXME */ } }; - -void Genode::Arm::flush_data_caches() -{ - asm volatile ("mcr p15, 0, %[rd], c7, c14, 0" :: [rd]"r"(0) : ); -} - - -void Genode::Arm::invalidate_data_caches() -{ - asm volatile ("mcr p15, 0, %[rd], c7, c6, 0" :: [rd]"r"(0) : ); -} - #endif /* _CPU_H_ */ diff --git a/repos/base-hw/src/core/include/spec/arm_v7/cpu_support.h b/repos/base-hw/src/core/include/spec/arm_v7/cpu_support.h index 070f64bcc..a7629f112 100644 --- a/repos/base-hw/src/core/include/spec/arm_v7/cpu_support.h +++ b/repos/base-hw/src/core/include/spec/arm_v7/cpu_support.h @@ -18,119 +18,6 @@ #include #include -/** - * Helpers that increase readability of MCR and MRC commands - */ -#define READ_CLIDR(rd) "mrc p15, 1, " #rd ", c0, c0, 1\n" -#define READ_CCSIDR(rd) "mrc p15, 1, " #rd ", c0, c0, 0\n" -#define WRITE_CSSELR(rs) "mcr p15, 2, " #rs ", c0, c0, 0\n" -#define WRITE_DCISW(rs) "mcr p15, 0, " #rs ", c7, c6, 2\n" -#define WRITE_DCCSW(rs) "mcr p15, 0, " #rs ", c7, c10, 2\n" - -/** - * First macro to do a set/way operation on all entries of all data caches - * - * Must be inserted directly before the targeted operation. Returns operand - * for targeted operation in R6. - */ -#define FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_0 \ - \ - /* get the cache level value (Clidr::Loc) */ \ - READ_CLIDR(r0) \ - "ands r3, r0, #0x7000000\n" \ - "mov r3, r3, lsr #23\n" \ - \ - /* skip all if cache level value is zero */ \ - "beq 5f\n" \ - "mov r9, #0\n" \ - \ - /* begin loop over cache numbers */ \ - "1:\n" \ - \ - /* work out 3 x cache level */ \ - "add r2, r9, r9, lsr #1\n" \ - \ - /* get the cache type of current cache number (Clidr::CtypeX) */ \ - "mov r1, r0, lsr r2\n" \ - "and r1, r1, #7\n" \ - "cmp r1, #2\n" \ - \ - /* skip cache number if there's no data cache at this level */ \ - "blt 4f\n" \ - \ - /* select the appropriate CCSIDR according to cache level and type */ \ - WRITE_CSSELR(r9) \ - "isb\n" \ - \ - /* get the line length of current cache (Ccsidr::LineSize) */ \ - READ_CCSIDR(r1) \ - "and r2, r1, #0x7\n" \ - \ - /* add 4 for the line-length offset (log2 of 16 bytes) */ \ - "add r2, r2, #4\n" \ - \ - /* get the associativity or max way size (Ccsidr::Associativity) */ \ - "ldr r4, =0x3ff\n" \ - "ands r4, r4, r1, lsr #3\n" \ - \ - /* get the bit position of the way-size increment */ \ - "clz r5, r4\n" \ - \ - /* get a working copy of the max way size */ \ - "mov r8, r4\n" \ - \ - /* begin loop over way numbers */ \ - "2:\n" \ - \ - /* get the number of sets or the max index size (Ccsidr::NumSets) */ \ - "ldr r7, =0x00007fff\n" \ - "ands r7, r7, r1, lsr #13\n" \ - \ - /* begin loop over indices */ \ - "3:\n" \ - \ - /* factor in the way number and cache number into write value */ \ - "orr r6, r9, r8, lsl r5\n" \ - \ - /* factor in the index number into write value */ \ - "orr r6, r6, r7, lsl r2\n" - -/** - * Second macro to do a set/way operation on all entries of all data caches - * - * Must be inserted directly after the targeted operation. - */ -#define FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_1 \ - \ - /* decrement the index */ \ - "subs r7, r7, #1\n" \ - \ - /* end loop over indices */ \ - "bge 3b\n" \ - \ - /* decrement the way number */ \ - "subs r8, r8, #1\n" \ - \ - /* end loop over way numbers */ \ - "bge 2b\n" \ - \ - /* label to skip a cache number */ \ - "4:\n" \ - \ - /* increment the cache number */ \ - "add r9, r9, #2\n" \ - "cmp r3, r9\n" \ - \ - /* end loop over cache numbers */ \ - "bgt 1b\n" \ - \ - /* synchronize data */ \ - "dsb\n" \ - \ - /* label to skip all */ \ - "5:\n" \ - ::: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" - namespace Genode { /** @@ -344,34 +231,4 @@ class Genode::Arm_v7 : public Arm asm volatile ("mcr p15, 4, %[rd], c12, c0, 0" :: [rd] "r" (a)); } }; - -void Genode::Arm::flush_data_caches() -{ - asm volatile ( - FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_0 - WRITE_DCCSW(r6) - FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_1); - Board::outer_cache_flush(); -} - - -void Genode::Arm::invalidate_data_caches() -{ - asm volatile ( - FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_0 - WRITE_DCISW(r6) - FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_1); - Board::outer_cache_invalidate(); -} - - -Genode::Arm::Psr::access_t Genode::Arm::Psr::init_user_with_trustzone() -{ - access_t v = 0; - M::set(v, M::USR); - I::set(v, 1); - A::set(v, 1); - return v; -} - #endif /* _SPEC__ARM_V7__CPU_SUPPORT_H_ */ diff --git a/repos/base-hw/src/core/include/spec/cortex_a8/cpu.h b/repos/base-hw/src/core/include/spec/cortex_a8/cpu.h index 63e31a015..046158a59 100644 --- a/repos/base-hw/src/core/include/spec/cortex_a8/cpu.h +++ b/repos/base-hw/src/core/include/spec/cortex_a8/cpu.h @@ -62,6 +62,7 @@ class Genode::Cpu : public Arm_v7 * adds translations solely before MMU and caches are enabled. */ if (is_user()) Kernel::update_data_region(addr, size); + else flush_data_caches(); } /** diff --git a/repos/base-hw/src/core/kernel/kernel.cc b/repos/base-hw/src/core/kernel/kernel.cc index bb6b9aa6f..cd21d38a2 100644 --- a/repos/base-hw/src/core/kernel/kernel.cc +++ b/repos/base-hw/src/core/kernel/kernel.cc @@ -40,14 +40,12 @@ #include using namespace Kernel; +extern "C" void _core_start(void); extern Genode::Native_thread_id _main_thread_id; -extern "C" void CORE_MAIN(); extern void * _start_secondary_cpus; extern int _prog_img_beg; extern int _prog_img_end; -Genode::Native_utcb * _main_thread_utcb; - namespace Kernel { /* import Genode types */ @@ -231,9 +229,11 @@ extern "C" void init_kernel_up() */ void init_kernel_mp_primary() { + using namespace Genode; + /* get stack memory that fullfills the constraints for core stacks */ enum { - STACK_ALIGNM = 1 << Genode::CORE_STACK_ALIGNM_LOG2, + STACK_ALIGNM = 1 << CORE_STACK_ALIGNM_LOG2, STACK_SIZE = DEFAULT_STACK_SIZE, }; static_assert(STACK_SIZE <= STACK_ALIGNM - sizeof(Core_thread_id), @@ -243,19 +243,27 @@ void init_kernel_mp_primary() /* provide thread ident at the aligned base of the stack */ *(Core_thread_id *)s = 0; + /* initialize UTCB and map it */ + static Native_utcb utcb __attribute__((aligned(get_page_size()))); + static Dataspace_component main_utcb_ds(sizeof(Native_utcb), + (addr_t)UTCB_MAIN_THREAD, + (addr_t)&utcb, CACHED, true, 0); + Genode::map_local((addr_t)&utcb, (addr_t)UTCB_MAIN_THREAD, + sizeof(Native_utcb) / get_page_size()); + + static Kernel::Thread t(Cpu_priority::max, 0, "core"); + /* start thread with stack pointer at the top of stack */ - static Native_utcb utcb; - static Thread t(Cpu_priority::max, 0, "core"); - _main_thread_id = t.id(); - _main_thread_utcb = &utcb; - _main_thread_utcb->start_info()->init(t.id(), Genode::Native_capability()); - t.ip = (addr_t)CORE_MAIN;; + utcb.start_info()->init(t.id(), + Dataspace_capability::local_cap(&main_utcb_ds)); + t.ip = (addr_t)&_core_start; t.sp = (addr_t)s + STACK_SIZE; - t.init(cpu_pool()->primary_cpu(), core_pd(), &utcb, 1); + t.init(cpu_pool()->primary_cpu(), core_pd(), + (Native_utcb*)Genode::UTCB_MAIN_THREAD, 1); /* initialize user interrupt objects */ - static Genode::uint8_t _irqs[Pic::NR_OF_IRQ * sizeof(User_irq)]; - for (unsigned i = 0; i < Pic::NR_OF_IRQ; i++) { + static Genode::uint8_t _irqs[Kernel::Pic::NR_OF_IRQ * sizeof(User_irq)]; + for (unsigned i = 0; i < Kernel::Pic::NR_OF_IRQ; i++) { if (private_interrupt(i)) { continue; } new (&_irqs[i * sizeof(User_irq)]) User_irq(i); } diff --git a/repos/base-hw/src/core/spec/arm/crt0.s b/repos/base-hw/src/core/spec/arm/crt0.s index 6c8d58dba..97982228c 100644 --- a/repos/base-hw/src/core/spec/arm/crt0.s +++ b/repos/base-hw/src/core/spec/arm/crt0.s @@ -1,93 +1,33 @@ -/* - * \brief Startup code for core - * \author Martin Stein +/** + * \brief Startup code for core on ARM * \author Stefan Kalkowski - * \date 2011-10-01 + * \date 2015-03-06 */ /* - * Copyright (C) 2011-2013 Genode Labs GmbH + * Copyright (C) 2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ -/************ - ** Macros ** - ************/ -/* core includes */ -.include "macros.s" +/************************** + ** .text (program code) ** + **************************/ +.section ".text" -/** - * Get base of the first kernel-stack and the common kernel-stack size - * - * \param base_dst_reg register that shall receive the stack-area base - * \param size_dst_reg register that shall receive the size of a kernel stack - */ -.macro _get_constraints_of_kernel_stacks base_dst_reg, size_dst_reg + /* program entry-point */ + .global _core_start + _core_start: - ldr \base_dst_reg, =kernel_stack - ldr \size_dst_reg, =kernel_stack_size - ldr \size_dst_reg, [\size_dst_reg] -.endm + /* create proper environment for main thread */ + bl init_main_thread + /* apply environment that was created by init_main_thread */ + ldr sp, =init_main_thread_result + ldr sp, [sp] -.section ".text.crt0" - - /********************************** - ** Startup code for primary CPU ** - **********************************/ - - .global _start - _start: - - /* idle a little initially because U-Boot likes it this way */ - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - - /* zero-fill BSS segment */ - ldr r0, =_bss_start - ldr r1, =_bss_end - mov r2, #0 - 1: - cmp r1, r0 - ble 2f - str r2, [r0] - add r0, r0, #4 - b 1b - 2: - - /* setup temporary stack pointer for uniprocessor mode */ - _get_constraints_of_kernel_stacks r0, r1 - add sp, r0, r1 - - /* uniprocessor kernel-initialization which activates multiprocessor */ - bl init_kernel_up - - /********************************************* - ** Startup code that is common to all CPUs ** - *********************************************/ - - .global _start_secondary_cpus - _start_secondary_cpus: - - /* setup multiprocessor-aware kernel stack-pointer */ - _get_constraints_of_kernel_stacks r0, r1 - _init_kernel_sp r0, r1 - - /* do multiprocessor kernel-initialization */ - bl init_kernel_mp - - /* call the kernel main-routine */ - bl kernel - - /* catch erroneous return of the kernel main-routine */ - 1: b 1b + /* jump into init C code instead of calling it as it should never return */ + b _main diff --git a/repos/base-hw/src/core/spec/arm/kernel/crt0.s b/repos/base-hw/src/core/spec/arm/kernel/crt0.s new file mode 100644 index 000000000..6c8d58dba --- /dev/null +++ b/repos/base-hw/src/core/spec/arm/kernel/crt0.s @@ -0,0 +1,93 @@ +/* + * \brief Startup code for core + * \author Martin Stein + * \author Stefan Kalkowski + * \date 2011-10-01 + */ + +/* + * Copyright (C) 2011-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/************ + ** Macros ** + ************/ + +/* core includes */ +.include "macros.s" + + +/** + * Get base of the first kernel-stack and the common kernel-stack size + * + * \param base_dst_reg register that shall receive the stack-area base + * \param size_dst_reg register that shall receive the size of a kernel stack + */ +.macro _get_constraints_of_kernel_stacks base_dst_reg, size_dst_reg + + ldr \base_dst_reg, =kernel_stack + ldr \size_dst_reg, =kernel_stack_size + ldr \size_dst_reg, [\size_dst_reg] +.endm + + +.section ".text.crt0" + + /********************************** + ** Startup code for primary CPU ** + **********************************/ + + .global _start + _start: + + /* idle a little initially because U-Boot likes it this way */ + mov r8, r8 + mov r8, r8 + mov r8, r8 + mov r8, r8 + mov r8, r8 + mov r8, r8 + mov r8, r8 + mov r8, r8 + + /* zero-fill BSS segment */ + ldr r0, =_bss_start + ldr r1, =_bss_end + mov r2, #0 + 1: + cmp r1, r0 + ble 2f + str r2, [r0] + add r0, r0, #4 + b 1b + 2: + + /* setup temporary stack pointer for uniprocessor mode */ + _get_constraints_of_kernel_stacks r0, r1 + add sp, r0, r1 + + /* uniprocessor kernel-initialization which activates multiprocessor */ + bl init_kernel_up + + /********************************************* + ** Startup code that is common to all CPUs ** + *********************************************/ + + .global _start_secondary_cpus + _start_secondary_cpus: + + /* setup multiprocessor-aware kernel stack-pointer */ + _get_constraints_of_kernel_stacks r0, r1 + _init_kernel_sp r0, r1 + + /* do multiprocessor kernel-initialization */ + bl init_kernel_mp + + /* call the kernel main-routine */ + bl kernel + + /* catch erroneous return of the kernel main-routine */ + 1: b 1b diff --git a/repos/base-hw/src/core/spec/arm_v6/cpu.cc b/repos/base-hw/src/core/spec/arm_v6/cpu.cc new file mode 100644 index 000000000..58fac14d2 --- /dev/null +++ b/repos/base-hw/src/core/spec/arm_v6/cpu.cc @@ -0,0 +1,22 @@ +/* + * \brief CPU driver for core + * \author Norman Feske + * \author Martin stein + * \author Stefan Kalkowski + * \date 2012-08-30 + */ + +/* + * Copyright (C) 2012-2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +void Genode::Arm::flush_data_caches() { + asm volatile ("mcr p15, 0, %[rd], c7, c14, 0" :: [rd]"r"(0) : ); } + +void Genode::Arm::invalidate_data_caches() { + asm volatile ("mcr p15, 0, %[rd], c7, c6, 0" :: [rd]"r"(0) : ); } diff --git a/repos/base-hw/src/core/spec/arm_v7/cpu.cc b/repos/base-hw/src/core/spec/arm_v7/cpu.cc new file mode 100644 index 000000000..c53cabc26 --- /dev/null +++ b/repos/base-hw/src/core/spec/arm_v7/cpu.cc @@ -0,0 +1,158 @@ +/* + * \brief CPU driver for core + * \author Martin stein + * \author Stefan Kalkowski + * \date 2011-11-03 + */ + +/* + * Copyright (C) 2011-2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +/** + * Helpers that increase readability of MCR and MRC commands + */ +#define READ_CLIDR(rd) "mrc p15, 1, " #rd ", c0, c0, 1\n" +#define READ_CCSIDR(rd) "mrc p15, 1, " #rd ", c0, c0, 0\n" +#define WRITE_CSSELR(rs) "mcr p15, 2, " #rs ", c0, c0, 0\n" +#define WRITE_DCISW(rs) "mcr p15, 0, " #rs ", c7, c6, 2\n" +#define WRITE_DCCSW(rs) "mcr p15, 0, " #rs ", c7, c10, 2\n" + +/** + * First macro to do a set/way operation on all entries of all data caches + * + * Must be inserted directly before the targeted operation. Returns operand + * for targeted operation in R6. + */ +#define FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_0 \ + \ + /* get the cache level value (Clidr::Loc) */ \ + READ_CLIDR(r0) \ + "ands r3, r0, #0x7000000\n" \ + "mov r3, r3, lsr #23\n" \ + \ + /* skip all if cache level value is zero */ \ + "beq 5f\n" \ + "mov r9, #0\n" \ + \ + /* begin loop over cache numbers */ \ + "1:\n" \ + \ + /* work out 3 x cache level */ \ + "add r2, r9, r9, lsr #1\n" \ + \ + /* get the cache type of current cache number (Clidr::CtypeX) */ \ + "mov r1, r0, lsr r2\n" \ + "and r1, r1, #7\n" \ + "cmp r1, #2\n" \ + \ + /* skip cache number if there's no data cache at this level */ \ + "blt 4f\n" \ + \ + /* select the appropriate CCSIDR according to cache level and type */ \ + WRITE_CSSELR(r9) \ + "isb\n" \ + \ + /* get the line length of current cache (Ccsidr::LineSize) */ \ + READ_CCSIDR(r1) \ + "and r2, r1, #0x7\n" \ + \ + /* add 4 for the line-length offset (log2 of 16 bytes) */ \ + "add r2, r2, #4\n" \ + \ + /* get the associativity or max way size (Ccsidr::Associativity) */ \ + "ldr r4, =0x3ff\n" \ + "ands r4, r4, r1, lsr #3\n" \ + \ + /* get the bit position of the way-size increment */ \ + "clz r5, r4\n" \ + \ + /* get a working copy of the max way size */ \ + "mov r8, r4\n" \ + \ + /* begin loop over way numbers */ \ + "2:\n" \ + \ + /* get the number of sets or the max index size (Ccsidr::NumSets) */ \ + "ldr r7, =0x00007fff\n" \ + "ands r7, r7, r1, lsr #13\n" \ + \ + /* begin loop over indices */ \ + "3:\n" \ + \ + /* factor in the way number and cache number into write value */ \ + "orr r6, r9, r8, lsl r5\n" \ + \ + /* factor in the index number into write value */ \ + "orr r6, r6, r7, lsl r2\n" + +/** + * Second macro to do a set/way operation on all entries of all data caches + * + * Must be inserted directly after the targeted operation. + */ +#define FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_1 \ + \ + /* decrement the index */ \ + "subs r7, r7, #1\n" \ + \ + /* end loop over indices */ \ + "bge 3b\n" \ + \ + /* decrement the way number */ \ + "subs r8, r8, #1\n" \ + \ + /* end loop over way numbers */ \ + "bge 2b\n" \ + \ + /* label to skip a cache number */ \ + "4:\n" \ + \ + /* increment the cache number */ \ + "add r9, r9, #2\n" \ + "cmp r3, r9\n" \ + \ + /* end loop over cache numbers */ \ + "bgt 1b\n" \ + \ + /* synchronize data */ \ + "dsb\n" \ + \ + /* label to skip all */ \ + "5:\n" \ + ::: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" + + +void Genode::Arm::flush_data_caches() +{ + asm volatile ( + FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_0 + WRITE_DCCSW(r6) + FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_1); + Board::outer_cache_flush(); +} + + +void Genode::Arm::invalidate_data_caches() +{ + asm volatile ( + FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_0 + WRITE_DCISW(r6) + FOR_ALL_SET_WAY_OF_ALL_DATA_CACHES_1); + Board::outer_cache_invalidate(); +} + + +Genode::Arm::Psr::access_t Genode::Arm::Psr::init_user_with_trustzone() +{ + access_t v = 0; + M::set(v, M::USR); + I::set(v, 1); + A::set(v, 1); + return v; +} diff --git a/repos/base-hw/src/core/thread_start.cc b/repos/base-hw/src/core/thread_start.cc index cc2b7ea7e..c9f9535ee 100644 --- a/repos/base-hw/src/core/thread_start.cc +++ b/repos/base-hw/src/core/thread_start.cc @@ -23,11 +23,10 @@ using namespace Genode; -extern Genode::Native_utcb * _main_thread_utcb; - -Native_utcb * main_thread_utcb() { - return _main_thread_utcb; } +namespace Genode { Rm_session * env_context_area_rm_session(); } +extern Ram_dataspace_capability _main_thread_utcb_ds; +extern Native_thread_id _main_thread_id; void Thread_base::start() { @@ -52,11 +51,23 @@ void Thread_base::_deinit_platform_thread() void Thread_base::_init_platform_thread(size_t, Type type) { - /* create platform thread */ - _tid.platform_thread = new (platform()->core_mem_alloc()) - Platform_thread(_context->name, &_context->utcb); + if (type == NORMAL) { + _tid.platform_thread = new (platform()->core_mem_alloc()) + Platform_thread(_context->name, &_context->utcb); + return; + } - if (type == NORMAL) { return; } + size_t const utcb_size = sizeof(Native_utcb); + addr_t const context_area = Native_config::context_area_virtual_base(); + addr_t const utcb_new = (addr_t)&_context->utcb - context_area; + Rm_session * const rm = env_context_area_rm_session(); - PWRN("not implemented!"); + /* remap initial main-thread UTCB according to context-area spec */ + try { rm->attach_at(_main_thread_utcb_ds, utcb_new, utcb_size); } + catch(...) { + PERR("failed to re-map UTCB"); + while (1) ; + } + /* adjust initial object state in case of a main thread */ + tid().thread_id = _main_thread_id; } diff --git a/repos/base/src/platform/_main.cc b/repos/base/src/platform/_main.cc index 9a8178885..29a3f7924 100644 --- a/repos/base/src/platform/_main.cc +++ b/repos/base/src/platform/_main.cc @@ -32,8 +32,6 @@ using namespace Genode; extern int main(int argc, char **argv, char **envp); -namespace Genode { Rm_session *env_context_area_rm_session(); } - enum { ATEXIT_SIZE = 256 };