mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-06 02:28:30 +00:00
hw: adjust core bootstrap to fit generic process
* Introduce hw-specific crt0 for core that calls e.g.: init_main_thread * re-map core's main thread UTCB to fit the right context area location * switch core's main thread's stack to fit the right context area location Fix #1440
This commit is contained in:
parent
2ad6a3b934
commit
657646e76e
@ -13,6 +13,7 @@ SRC_CC += spec/arm/kernel/thread.cc
|
|||||||
SRC_CC += spec/arm/kernel/cpu.cc
|
SRC_CC += spec/arm/kernel/cpu.cc
|
||||||
|
|
||||||
# add assembly sources
|
# add assembly sources
|
||||||
|
SRC_S += spec/arm/kernel/crt0.s
|
||||||
SRC_S += spec/arm/crt0.s
|
SRC_S += spec/arm/crt0.s
|
||||||
|
|
||||||
# include less specific configuration
|
# include less specific configuration
|
||||||
|
@ -11,6 +11,7 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/arm_v6
|
|||||||
SRC_CC += spec/arm/cpu.cc
|
SRC_CC += spec/arm/cpu.cc
|
||||||
SRC_CC += spec/arm/kernel/cpu_context.cc
|
SRC_CC += spec/arm/kernel/cpu_context.cc
|
||||||
SRC_CC += kernel/vm_thread.cc
|
SRC_CC += kernel/vm_thread.cc
|
||||||
|
SRC_CC += spec/arm_v6/cpu.cc
|
||||||
|
|
||||||
# add assembly sources
|
# add assembly sources
|
||||||
SRC_S += spec/arm_v6/mode_transition.s
|
SRC_S += spec/arm_v6/mode_transition.s
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
# add include paths
|
# add include paths
|
||||||
INC_DIR += $(REP_DIR)/src/core/include/spec/arm_v7
|
INC_DIR += $(REP_DIR)/src/core/include/spec/arm_v7
|
||||||
|
|
||||||
|
# add C++ sources
|
||||||
|
SRC_CC += spec/arm_v7/cpu.cc
|
||||||
|
|
||||||
# add assembly sources
|
# add assembly sources
|
||||||
SRC_S += spec/arm_v7/mode_transition.s
|
SRC_S += spec/arm_v7/mode_transition.s
|
||||||
|
|
||||||
|
@ -7,9 +7,6 @@
|
|||||||
# add library dependencies
|
# add library dependencies
|
||||||
LIBS += core-perf_counter
|
LIBS += core-perf_counter
|
||||||
|
|
||||||
# set entry point of core's first thread
|
|
||||||
CC_OPT += -DCORE_MAIN=_main
|
|
||||||
|
|
||||||
# add library dependencies
|
# add library dependencies
|
||||||
LIBS += base-common
|
LIBS += base-common
|
||||||
|
|
||||||
@ -54,6 +51,7 @@ SRC_CC += kernel/signal_receiver.cc
|
|||||||
SRC_CC += kernel/irq.cc
|
SRC_CC += kernel/irq.cc
|
||||||
SRC_CC += kernel/pd.cc
|
SRC_CC += kernel/pd.cc
|
||||||
SRC_CC += kernel/cpu.cc
|
SRC_CC += kernel/cpu.cc
|
||||||
|
SRC_CC += init_main_thread.cc
|
||||||
|
|
||||||
# add assembly sources
|
# add assembly sources
|
||||||
SRC_S += boot_modules.s
|
SRC_S += boot_modules.s
|
||||||
|
@ -63,12 +63,10 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
|||||||
** Thread_base **
|
** Thread_base **
|
||||||
*****************/
|
*****************/
|
||||||
|
|
||||||
extern Native_utcb* main_thread_utcb();
|
|
||||||
|
|
||||||
Native_utcb * Thread_base::utcb()
|
Native_utcb * Thread_base::utcb()
|
||||||
{
|
{
|
||||||
if (this) { return &_context->utcb; }
|
if (this) { return &_context->utcb; }
|
||||||
return main_thread_utcb();
|
return UTCB_MAIN_THREAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,12 +26,6 @@ extern Ram_dataspace_capability _main_thread_utcb_ds;
|
|||||||
extern Native_thread_id _main_thread_id;
|
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 **
|
** Thread_base **
|
||||||
*****************/
|
*****************/
|
||||||
|
@ -252,7 +252,7 @@ class Genode::Arm
|
|||||||
/**
|
/**
|
||||||
* Return value initialized for user execution with trustzone
|
* 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'
|
* Do common initialization on register value 'v'
|
||||||
@ -467,12 +467,12 @@ class Genode::Arm
|
|||||||
/**
|
/**
|
||||||
* Flush all entries of all data caches
|
* 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
|
* Invalidate all entries of all data caches
|
||||||
*/
|
*/
|
||||||
inline static void invalidate_data_caches();
|
static void invalidate_data_caches();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush all caches
|
* Flush all caches
|
||||||
|
@ -160,6 +160,7 @@ class Genode::Cpu : public Arm
|
|||||||
* adds translations solely before MMU and caches are enabled.
|
* adds translations solely before MMU and caches are enabled.
|
||||||
*/
|
*/
|
||||||
if (is_user()) Kernel::update_data_region(addr, size);
|
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 */ }
|
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_ */
|
#endif /* _CPU_H_ */
|
||||||
|
@ -18,119 +18,6 @@
|
|||||||
#include <spec/arm/cpu_support.h>
|
#include <spec/arm/cpu_support.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
namespace Genode
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -344,34 +231,4 @@ class Genode::Arm_v7 : public Arm
|
|||||||
asm volatile ("mcr p15, 4, %[rd], c12, c0, 0" :: [rd] "r" (a)); }
|
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_ */
|
#endif /* _SPEC__ARM_V7__CPU_SUPPORT_H_ */
|
||||||
|
@ -62,6 +62,7 @@ class Genode::Cpu : public Arm_v7
|
|||||||
* adds translations solely before MMU and caches are enabled.
|
* adds translations solely before MMU and caches are enabled.
|
||||||
*/
|
*/
|
||||||
if (is_user()) Kernel::update_data_region(addr, size);
|
if (is_user()) Kernel::update_data_region(addr, size);
|
||||||
|
else flush_data_caches();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,14 +40,12 @@
|
|||||||
#include <kernel/perf_counter.h>
|
#include <kernel/perf_counter.h>
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
|
extern "C" void _core_start(void);
|
||||||
extern Genode::Native_thread_id _main_thread_id;
|
extern Genode::Native_thread_id _main_thread_id;
|
||||||
extern "C" void CORE_MAIN();
|
|
||||||
extern void * _start_secondary_cpus;
|
extern void * _start_secondary_cpus;
|
||||||
extern int _prog_img_beg;
|
extern int _prog_img_beg;
|
||||||
extern int _prog_img_end;
|
extern int _prog_img_end;
|
||||||
|
|
||||||
Genode::Native_utcb * _main_thread_utcb;
|
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
/* import Genode types */
|
/* import Genode types */
|
||||||
@ -231,9 +229,11 @@ extern "C" void init_kernel_up()
|
|||||||
*/
|
*/
|
||||||
void init_kernel_mp_primary()
|
void init_kernel_mp_primary()
|
||||||
{
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
/* get stack memory that fullfills the constraints for core stacks */
|
/* get stack memory that fullfills the constraints for core stacks */
|
||||||
enum {
|
enum {
|
||||||
STACK_ALIGNM = 1 << Genode::CORE_STACK_ALIGNM_LOG2,
|
STACK_ALIGNM = 1 << CORE_STACK_ALIGNM_LOG2,
|
||||||
STACK_SIZE = DEFAULT_STACK_SIZE,
|
STACK_SIZE = DEFAULT_STACK_SIZE,
|
||||||
};
|
};
|
||||||
static_assert(STACK_SIZE <= STACK_ALIGNM - sizeof(Core_thread_id),
|
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 */
|
/* provide thread ident at the aligned base of the stack */
|
||||||
*(Core_thread_id *)s = 0;
|
*(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 */
|
/* start thread with stack pointer at the top of stack */
|
||||||
static Native_utcb utcb;
|
utcb.start_info()->init(t.id(),
|
||||||
static Thread t(Cpu_priority::max, 0, "core");
|
Dataspace_capability::local_cap(&main_utcb_ds));
|
||||||
_main_thread_id = t.id();
|
t.ip = (addr_t)&_core_start;
|
||||||
_main_thread_utcb = &utcb;
|
|
||||||
_main_thread_utcb->start_info()->init(t.id(), Genode::Native_capability());
|
|
||||||
t.ip = (addr_t)CORE_MAIN;;
|
|
||||||
t.sp = (addr_t)s + STACK_SIZE;
|
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 */
|
/* initialize user interrupt objects */
|
||||||
static Genode::uint8_t _irqs[Pic::NR_OF_IRQ * sizeof(User_irq)];
|
static Genode::uint8_t _irqs[Kernel::Pic::NR_OF_IRQ * sizeof(User_irq)];
|
||||||
for (unsigned i = 0; i < Pic::NR_OF_IRQ; i++) {
|
for (unsigned i = 0; i < Kernel::Pic::NR_OF_IRQ; i++) {
|
||||||
if (private_interrupt(i)) { continue; }
|
if (private_interrupt(i)) { continue; }
|
||||||
new (&_irqs[i * sizeof(User_irq)]) User_irq(i);
|
new (&_irqs[i * sizeof(User_irq)]) User_irq(i);
|
||||||
}
|
}
|
||||||
|
@ -1,93 +1,33 @@
|
|||||||
/*
|
/**
|
||||||
* \brief Startup code for core
|
* \brief Startup code for core on ARM
|
||||||
* \author Martin Stein
|
|
||||||
* \author Stefan Kalkowski
|
* \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
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/************
|
|
||||||
** Macros **
|
|
||||||
************/
|
|
||||||
|
|
||||||
/* core includes */
|
/**************************
|
||||||
.include "macros.s"
|
** .text (program code) **
|
||||||
|
**************************/
|
||||||
|
|
||||||
|
.section ".text"
|
||||||
|
|
||||||
/**
|
/* program entry-point */
|
||||||
* Get base of the first kernel-stack and the common kernel-stack size
|
.global _core_start
|
||||||
*
|
_core_start:
|
||||||
* \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
|
/* create proper environment for main thread */
|
||||||
ldr \size_dst_reg, =kernel_stack_size
|
bl init_main_thread
|
||||||
ldr \size_dst_reg, [\size_dst_reg]
|
|
||||||
.endm
|
|
||||||
|
|
||||||
|
/* apply environment that was created by init_main_thread */
|
||||||
|
ldr sp, =init_main_thread_result
|
||||||
|
ldr sp, [sp]
|
||||||
|
|
||||||
.section ".text.crt0"
|
/* jump into init C code instead of calling it as it should never return */
|
||||||
|
b _main
|
||||||
/**********************************
|
|
||||||
** 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
|
|
||||||
|
93
repos/base-hw/src/core/spec/arm/kernel/crt0.s
Normal file
93
repos/base-hw/src/core/spec/arm/kernel/crt0.s
Normal file
@ -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
|
22
repos/base-hw/src/core/spec/arm_v6/cpu.cc
Normal file
22
repos/base-hw/src/core/spec/arm_v6/cpu.cc
Normal file
@ -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 <cpu.h>
|
||||||
|
|
||||||
|
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) : ); }
|
158
repos/base-hw/src/core/spec/arm_v7/cpu.cc
Normal file
158
repos/base-hw/src/core/spec/arm_v7/cpu.cc
Normal file
@ -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 <cpu.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
@ -23,11 +23,10 @@
|
|||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
extern Genode::Native_utcb * _main_thread_utcb;
|
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||||
|
|
||||||
Native_utcb * main_thread_utcb() {
|
|
||||||
return _main_thread_utcb; }
|
|
||||||
|
|
||||||
|
extern Ram_dataspace_capability _main_thread_utcb_ds;
|
||||||
|
extern Native_thread_id _main_thread_id;
|
||||||
|
|
||||||
void Thread_base::start()
|
void Thread_base::start()
|
||||||
{
|
{
|
||||||
@ -52,11 +51,23 @@ void Thread_base::_deinit_platform_thread()
|
|||||||
|
|
||||||
void Thread_base::_init_platform_thread(size_t, Type type)
|
void Thread_base::_init_platform_thread(size_t, Type type)
|
||||||
{
|
{
|
||||||
/* create platform thread */
|
if (type == NORMAL) {
|
||||||
_tid.platform_thread = new (platform()->core_mem_alloc())
|
_tid.platform_thread = new (platform()->core_mem_alloc())
|
||||||
Platform_thread(_context->name, &_context->utcb);
|
Platform_thread(_context->name, &_context->utcb);
|
||||||
|
return;
|
||||||
if (type == NORMAL) { return; }
|
}
|
||||||
|
|
||||||
PWRN("not implemented!");
|
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();
|
||||||
|
|
||||||
|
/* 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;
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,6 @@ using namespace Genode;
|
|||||||
|
|
||||||
extern int main(int argc, char **argv, char **envp);
|
extern int main(int argc, char **argv, char **envp);
|
||||||
|
|
||||||
namespace Genode { Rm_session *env_context_area_rm_session(); }
|
|
||||||
|
|
||||||
enum { ATEXIT_SIZE = 256 };
|
enum { ATEXIT_SIZE = 256 };
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user