mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +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
|
||||
|
||||
# add assembly sources
|
||||
SRC_S += spec/arm/kernel/crt0.s
|
||||
SRC_S += spec/arm/crt0.s
|
||||
|
||||
# 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/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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 **
|
||||
*****************/
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -18,119 +18,6 @@
|
||||
#include <spec/arm/cpu_support.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
|
||||
{
|
||||
/**
|
||||
@ -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_ */
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,14 +40,12 @@
|
||||
#include <kernel/perf_counter.h>
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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 };
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user