diff --git a/repos/base-hw/lib/mk/arm_v6/core.inc b/repos/base-hw/lib/mk/arm_v6/core.inc index e517e445a8..f0a6fee3eb 100644 --- a/repos/base-hw/lib/mk/arm_v6/core.inc +++ b/repos/base-hw/lib/mk/arm_v6/core.inc @@ -8,7 +8,7 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/arm_v6 # add C++ sources -SRC_CC += cpu.cc +SRC_CC += spec/arm/cpu.cc # add assembly sources SRC_S += spec/arm_v6/mode_transition.s diff --git a/repos/base-hw/lib/mk/cortex_a15/core.inc b/repos/base-hw/lib/mk/cortex_a15/core.inc new file mode 100644 index 0000000000..68e23801b8 --- /dev/null +++ b/repos/base-hw/lib/mk/cortex_a15/core.inc @@ -0,0 +1,11 @@ +# +# \brief Build config for Genodes core process +# \author Stefan Kalkowski +# \date 2014-09-02 +# + +# add include paths +INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a15 + +# include less specific configuration +include $(REP_DIR)/lib/mk/arm_v7/core.inc diff --git a/repos/base-hw/lib/mk/cortex_a8/core.inc b/repos/base-hw/lib/mk/cortex_a8/core.inc new file mode 100644 index 0000000000..cb68abc269 --- /dev/null +++ b/repos/base-hw/lib/mk/cortex_a8/core.inc @@ -0,0 +1,14 @@ +# +# \brief Build config for Genodes core process +# \author Stefan Kalkowski +# \date 2014-09-02 +# + +# add include paths +INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a8 + +# add C++ sources +SRC_CC += spec/arm/cpu.cc + +# include less specific configuration +include $(REP_DIR)/lib/mk/arm_v7/core.inc diff --git a/repos/base-hw/lib/mk/cortex_a9/core.inc b/repos/base-hw/lib/mk/cortex_a9/core.inc new file mode 100644 index 0000000000..57d287c3d3 --- /dev/null +++ b/repos/base-hw/lib/mk/cortex_a9/core.inc @@ -0,0 +1,14 @@ +# +# \brief Build config for Genodes core process +# \author Stefan Kalkowski +# \date 2014-09-02 +# + +# add include paths +INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a9 + +# add C++ sources +SRC_CC += spec/arm/cpu.cc + +# include less specific configuration +include $(REP_DIR)/lib/mk/arm_v7/core.inc diff --git a/repos/base-hw/lib/mk/exynos5/core.mk b/repos/base-hw/lib/mk/exynos5/core.mk index 34ba13185e..ce914f7793 100644 --- a/repos/base-hw/lib/mk/exynos5/core.mk +++ b/repos/base-hw/lib/mk/exynos5/core.mk @@ -16,4 +16,4 @@ SRC_CC += platform_services.cc SRC_CC += spec/arm_gic/pic.cc # include less specific configuration -include $(REP_DIR)/lib/mk/arm_v7/core.inc +include $(REP_DIR)/lib/mk/cortex_a15/core.inc diff --git a/repos/base-hw/lib/mk/platform_imx53/core.mk b/repos/base-hw/lib/mk/platform_imx53/core.mk index 142fe640bd..240305e081 100644 --- a/repos/base-hw/lib/mk/platform_imx53/core.mk +++ b/repos/base-hw/lib/mk/platform_imx53/core.mk @@ -13,8 +13,5 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/imx53 INC_DIR += $(REP_DIR)/src/core/include/spec/imx INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a8 -# add C++ sources -SRC_CC += cpu.cc - # include less specific configuration -include $(REP_DIR)/lib/mk/arm_v7/core.inc +include $(REP_DIR)/lib/mk/cortex_a8/core.inc diff --git a/repos/base-hw/lib/mk/platform_panda/core.mk b/repos/base-hw/lib/mk/platform_panda/core.mk index 0566160b02..3eba25fb90 100644 --- a/repos/base-hw/lib/mk/platform_panda/core.mk +++ b/repos/base-hw/lib/mk/platform_panda/core.mk @@ -15,7 +15,6 @@ SRC_CC += platform_services.cc SRC_CC += spec/panda/platform_support.cc SRC_CC += spec/cortex_a9/pic.cc SRC_CC += spec/arm_gic/pic.cc -SRC_CC += cpu.cc # include less specific configuration -include $(REP_DIR)/lib/mk/arm_v7/core.inc +include $(REP_DIR)/lib/mk/cortex_a9/core.inc diff --git a/repos/base-hw/lib/mk/platform_pbxa9/core.mk b/repos/base-hw/lib/mk/platform_pbxa9/core.mk index b42dd1aaf8..22844cf2c9 100644 --- a/repos/base-hw/lib/mk/platform_pbxa9/core.mk +++ b/repos/base-hw/lib/mk/platform_pbxa9/core.mk @@ -15,7 +15,6 @@ SRC_CC += platform_services.cc SRC_CC += spec/pbxa9/platform_support.cc SRC_CC += spec/cortex_a9/pic.cc SRC_CC += spec/arm_gic/pic.cc -SRC_CC += cpu.cc # include less specific configuration -include $(REP_DIR)/lib/mk/arm_v7/core.inc +include $(REP_DIR)/lib/mk/cortex_a9/core.inc diff --git a/repos/base-hw/lib/mk/platform_vea9x4/core.mk b/repos/base-hw/lib/mk/platform_vea9x4/core.mk index 1f06b60407..7d7a4d56aa 100644 --- a/repos/base-hw/lib/mk/platform_vea9x4/core.mk +++ b/repos/base-hw/lib/mk/platform_vea9x4/core.mk @@ -11,11 +11,10 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/cortex_a9 INC_DIR += $(REP_DIR)/src/core/include/spec/pl011 # add C++ sources -SRC_CC += cpu.cc SRC_CC += platform_services.cc SRC_CC += spec/vea9x4/platform_support.cc SRC_CC += spec/cortex_a9/pic.cc SRC_CC += spec/arm_gic/pic.cc # include less specific configuration -include $(REP_DIR)/lib/mk/arm_v7/core.inc +include $(REP_DIR)/lib/mk/cortex_a9/core.inc diff --git a/repos/base-hw/src/core/cpu.cc b/repos/base-hw/src/core/cpu.cc deleted file mode 100644 index 74a0179180..0000000000 --- a/repos/base-hw/src/core/cpu.cc +++ /dev/null @@ -1,21 +0,0 @@ -/* - * \brief CPU driver for core - * \author Martin stein - * \date 2014-07-14 - */ - -/* - * Copyright (C) 2011-2014 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. - */ - -/* core includes */ -#include - -using namespace Genode; - -unsigned Cpu::primary_id() { return 0; } - -unsigned Cpu::executing_id() { return primary_id(); } diff --git a/repos/base-hw/src/core/include/kernel/early_translations.h b/repos/base-hw/src/core/include/kernel/early_translations.h index a648f695cd..82081c9377 100644 --- a/repos/base-hw/src/core/include/kernel/early_translations.h +++ b/repos/base-hw/src/core/include/kernel/early_translations.h @@ -16,6 +16,7 @@ #define _KERNEL__EARLY_TRANSLATIONS_H_ /* core includes */ +#include #include #include diff --git a/repos/base-hw/src/core/include/platform_pd.h b/repos/base-hw/src/core/include/platform_pd.h index 87f1354eeb..6701c1e596 100644 --- a/repos/base-hw/src/core/include/platform_pd.h +++ b/repos/base-hw/src/core/include/platform_pd.h @@ -18,6 +18,7 @@ /* Genode includes */ #include #include +#include /* Core includes */ #include @@ -80,7 +81,7 @@ namespace Genode throw Root::Quota_exceeded(); } - _tt = new (tt) Translation_table(); + _tt = construct_at(tt); _tt_phys = (Translation_table*) cma->phys_addr(_tt); _pslab = new (cma) Page_slab(cma); Kernel::mtc()->map(_tt, _pslab); 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 76a8dd4c6e..2e2cef134a 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 @@ -336,20 +336,27 @@ class Genode::Arm */ struct Context : Cpu_state { - Cidr::access_t cidr; - Ttbr0::access_t ttbr0; + /** + * TODO: currently all non-Cortex A15 platforms use the + * short translation table format and thereby the Context ID + * register to store the ASID, and the TTBR0 for the table + * address. Cortex A15 uses the long translation format and + * a 64-bit wide TTBR0 that holds all information. + * The current Cortex A15 implementation stores TTBR0 in both + * members stated below. + */ + uint32_t cidr; + uint32_t ttbr0; /** * Return base of assigned translation table */ - addr_t translation_table() const { - return Ttbr0::Ba::masked(ttbr0); } + addr_t translation_table() const; /** * Assign translation-table base 'table' */ - void translation_table(addr_t const table) { - ttbr0 = Arm::Ttbr0::init(table); } + void translation_table(addr_t const table); /** * Assign protection domain @@ -405,35 +412,7 @@ class Genode::Arm * \param va holds the virtual fault-address if call returns 1 * \param w holds wether it's a write fault if call returns 1 */ - bool in_fault(addr_t & va, addr_t & w) const - { - switch (cpu_exception) { - - case PREFETCH_ABORT: { - - /* check if fault was caused by a translation miss */ - Ifsr::access_t const fs = Ifsr::Fs::get(Ifsr::read()); - if (fs != Ifsr::section && fs != Ifsr::page) { return 0; } - - /* fetch fault data */ - w = 0; - va = ip; - return 1; } - - case DATA_ABORT: { - - /* check if fault was caused by translation miss */ - Dfsr::access_t const fs = Dfsr::Fs::get(Dfsr::read()); - if (fs != Dfsr::section && fs != Dfsr::page) { return 0; } - - /* fetch fault data */ - Dfsr::access_t const dfsr = Dfsr::read(); - w = Dfsr::Wnr::get(dfsr); - va = Dfar::read(); - return 1; } - - default: return 0; } - } + bool in_fault(addr_t & va, addr_t & w) const; }; /** diff --git a/repos/base-hw/src/core/include/spec/arm/macros_support.s b/repos/base-hw/src/core/include/spec/arm/macros_support.s index 639ef3c3cb..87d440a0cf 100644 --- a/repos/base-hw/src/core/include/spec/arm/macros_support.s +++ b/repos/base-hw/src/core/include/spec/arm/macros_support.s @@ -53,3 +53,72 @@ /* alignment constraints */ .set MIN_PAGE_SIZE_LOG2, 12 .set DATA_ACCESS_ALIGNM_LOG2, 2 + + +/*************************************************** + ** Constant values that the mode transition uses ** + ***************************************************/ + +/* kernel names of exceptions that can interrupt a user */ +.set RST_TYPE, 1 +.set UND_TYPE, 2 +.set SVC_TYPE, 3 +.set PAB_TYPE, 4 +.set DAB_TYPE, 5 +.set IRQ_TYPE, 6 +.set FIQ_TYPE, 7 + +.set RST_PC_ADJUST, 0 +.set UND_PC_ADJUST, 4 +.set SVC_PC_ADJUST, 0 +.set PAB_PC_ADJUST, 4 +.set DAB_PC_ADJUST, 8 +.set IRQ_PC_ADJUST, 4 +.set FIQ_PC_ADJUST, 4 + +/* offsets of the member variables in a CPU context */ +.set R12_OFFSET, 12 * 4 +.set SP_OFFSET, 13 * 4 +.set LR_OFFSET, 14 * 4 +.set PC_OFFSET, 15 * 4 +.set PSR_OFFSET, 16 * 4 +.set EXCEPTION_TYPE_OFFSET, 17 * 4 +.set TRANSIT_TTBR0_OFFSET, 17 * 4 +.set CIDR_OFFSET, 18 * 4 +.set TTBR0_OFFSET, 19 * 4 + +/* size of local variables */ +.set CONTEXT_PTR_SIZE, 1 * 4 + + +/********************************************************* + ** Local data structures that the mode transition uses ** + *********************************************************/ + +.macro _mt_local_variables + + /* space for a copy of the kernel context */ + .p2align 2 + .global _mt_master_context_begin + _mt_master_context_begin: + .space 32 * 4 + .global _mt_master_context_end + _mt_master_context_end: + + /* space for a client context-pointer per CPU */ + .p2align 2 + .global _mt_client_context_ptr + _mt_client_context_ptr: + .rept NR_OF_CPUS + .space CONTEXT_PTR_SIZE + .endr + + /* a globally mapped buffer per CPU */ + .p2align 2 + .global _mt_buffer + _mt_buffer: + .rept NR_OF_CPUS + .space BUFFER_SIZE + .endr + +.endm /* _mt_local_variables */ diff --git a/repos/base-hw/src/core/include/spec/arm/mode_transition.s b/repos/base-hw/src/core/include/spec/arm/mode_transition.s deleted file mode 100644 index eabc623407..0000000000 --- a/repos/base-hw/src/core/include/spec/arm/mode_transition.s +++ /dev/null @@ -1,80 +0,0 @@ -/* - * \brief Mode transition definitions used by all ARM architectures - * \author Stefan Kalkowski - * \date 2014-06-12 - */ - -/* - * Copyright (C) 2014 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. - */ - -/*************************************************** - ** Constant values that the mode transition uses ** - ***************************************************/ - -/* kernel names of exceptions that can interrupt a user */ -.set RST_TYPE, 1 -.set UND_TYPE, 2 -.set SVC_TYPE, 3 -.set PAB_TYPE, 4 -.set DAB_TYPE, 5 -.set IRQ_TYPE, 6 -.set FIQ_TYPE, 7 - -.set RST_PC_ADJUST, 0 -.set UND_PC_ADJUST, 4 -.set SVC_PC_ADJUST, 0 -.set PAB_PC_ADJUST, 4 -.set DAB_PC_ADJUST, 8 -.set IRQ_PC_ADJUST, 4 -.set FIQ_PC_ADJUST, 4 - -/* offsets of the member variables in a CPU context */ -.set R12_OFFSET, 12 * 4 -.set SP_OFFSET, 13 * 4 -.set LR_OFFSET, 14 * 4 -.set PC_OFFSET, 15 * 4 -.set PSR_OFFSET, 16 * 4 -.set EXCEPTION_TYPE_OFFSET, 17 * 4 -.set TRANSIT_TTBR0_OFFSET, 17 * 4 -.set CIDR_OFFSET, 18 * 4 -.set TTBR0_OFFSET, 19 * 4 - -/* size of local variables */ -.set CONTEXT_PTR_SIZE, 1 * 4 - - -/********************************************************* - ** Local data structures that the mode transition uses ** - *********************************************************/ - -.macro _mt_local_variables - - /* space for a copy of the kernel context */ - .p2align 2 - .global _mt_master_context_begin - _mt_master_context_begin: - .space 32 * 4 - .global _mt_master_context_end - _mt_master_context_end: - - /* space for a client context-pointer per CPU */ - .p2align 2 - .global _mt_client_context_ptr - _mt_client_context_ptr: - .rept NR_OF_CPUS - .space CONTEXT_PTR_SIZE - .endr - - /* a globally mapped buffer per CPU */ - .p2align 2 - .global _mt_buffer - _mt_buffer: - .rept NR_OF_CPUS - .space BUFFER_SIZE - .endr - -.endm /* _mt_local_variables */ diff --git a/repos/base-hw/src/core/include/spec/arm_v7/macros.s b/repos/base-hw/src/core/include/spec/arm_v7/macros_support.s similarity index 100% rename from repos/base-hw/src/core/include/spec/arm_v7/macros.s rename to repos/base-hw/src/core/include/spec/arm_v7/macros_support.s diff --git a/repos/base-hw/src/core/include/spec/cortex_a15/cpu.h b/repos/base-hw/src/core/include/spec/cortex_a15/cpu.h index 137546d37a..47275aeb4e 100644 --- a/repos/base-hw/src/core/include/spec/cortex_a15/cpu.h +++ b/repos/base-hw/src/core/include/spec/cortex_a15/cpu.h @@ -34,8 +34,82 @@ namespace Kernel { using Genode::Cpu_lazy_state; } class Genode::Cpu : public Arm_v7 { + protected: + + /** + * Translation table base control register + */ + struct Ttbcr : Arm::Ttbcr + { + struct Irgn0 : Bitfield<8, 2> { }; + struct Orgn0 : Bitfield<10, 2> { }; + struct Sh0 : Bitfield<12, 2> { }; + struct Eae : Bitfield<31, 1> { }; /* extended address enable */ + + static access_t init_virt_kernel() + { + access_t v = 0; + Irgn0::set(v, 1); + Orgn0::set(v, 1); + Sh0::set(v, 0b10); + Eae::set(v, 1); + return v; + } + }; + + struct Mair0 : Register<32> + { + static void init() + { + access_t v = 0xff0044; + asm volatile ("mcr p15, 0, %[v], c10, c2, 0" :: [v]"r"(v) : ); + } + }; + public: + /** + * Translation table base register 0 (64-bit format) + */ + struct Ttbr0 : Register<64> + { + enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 }; + + struct Ba : Bitfield<5, 34> { }; /* translation table base */ + struct Asid : Bitfield<48,8> { }; + + static void write(access_t const v) + { + asm volatile ("mcrr p15, 0, %[v0], %[v1], c2" + :: [v0]"r"(v), [v1]"r"(v >> 32) : ); + } + + static access_t read() + { + uint32_t v0, v1; + asm volatile ("mrrc p15, 0, %[v0], %[v1], c2" + : [v0]"=r"(v0), [v1]"=r"(v1) :: ); + return (access_t) v0 | ((access_t)v1 << 32); + } + + /** + * Return initialized value + * + * \param table base of targeted translation table + */ + static access_t init(addr_t const table, unsigned const id) + { + access_t v = Ba::masked((access_t)table); + Asid::set(v, id); + return v; + } + + static Genode::uint32_t init(addr_t const table) { + return table; } + + }; + + /** * Return wether to retry an undefined user instruction after this call */ @@ -51,6 +125,24 @@ class Genode::Cpu : public Arm_v7 */ static unsigned primary_id(); + /** + * Switch to the virtual mode in kernel + * + * \param table base of targeted translation table + * \param process_id process ID of the kernel address-space + */ + static void + init_virt_kernel(addr_t const table, unsigned const process_id) + { + Mair0::init(); + Cidr::write(process_id); + Dacr::write(Dacr::init_virt_kernel()); + Ttbr0::write(Ttbr0::init(table, 1)); + Ttbcr::write(Ttbcr::init_virt_kernel()); + Sctlr::write(Sctlr::init_virt_kernel()); + inval_branch_predicts(); + } + /************* ** Dummies ** *************/ diff --git a/repos/base-hw/src/core/include/spec/cortex_a15/macros.s b/repos/base-hw/src/core/include/spec/cortex_a15/macros.s new file mode 100644 index 0000000000..712e2dab6f --- /dev/null +++ b/repos/base-hw/src/core/include/spec/cortex_a15/macros.s @@ -0,0 +1,38 @@ +/* + * \brief Macros that are used by multiple assembly files + * \author Stefan Kalkowski + * \date 2015-01-30 + */ + +/* + * 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. + */ + +/* core includes */ +.include "spec/arm_v7/macros_support.s" + + +/** + * Switch to a given protection domain + * + * There is no atomicity problem when setting the ASID and translation table + * base address in the one 64-bit TTBR0 register, like in Armv7 cpus without + * LPAE extensions. Therefore, we don't have to use a transition table. + * + * \param transit_ttbr0 ignored parameter + * \param new_cidr new CIDR value, read reg + * \param new_ttbr0 new TTBR0 value, read/write reg + */ +.macro _switch_protection_domain transit_ttbr0, new_cidr, new_ttbr0 + + /* write translation-table-base register 0 */ + lsl \new_cidr, \new_cidr, #16 + mcrr p15, 0, \new_ttbr0, \new_cidr, c2 + + /* instruction and data synchronization barrier */ + isb + dsb +.endm diff --git a/repos/base-hw/src/core/include/spec/cortex_a15/translation_table.h b/repos/base-hw/src/core/include/spec/cortex_a15/translation_table.h new file mode 100644 index 0000000000..9b6fcc5b89 --- /dev/null +++ b/repos/base-hw/src/core/include/spec/cortex_a15/translation_table.h @@ -0,0 +1,18 @@ +/* + * \brief Translation table definitions for core + * \author Stefan Kalkowski + * \date 2015-01-30 + */ +/* + * 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. + */ +#ifndef _TRANSLATION_TABLE_H_ +#define _TRANSLATION_TABLE_H_ + +/* core includes */ +#include + +#endif /* _TRANSLATION_TABLE_H_ */ diff --git a/repos/base-hw/src/core/include/spec/cortex_a8/macros.s b/repos/base-hw/src/core/include/spec/cortex_a8/macros.s new file mode 100644 index 0000000000..5166afb4de --- /dev/null +++ b/repos/base-hw/src/core/include/spec/cortex_a8/macros.s @@ -0,0 +1,31 @@ +/* + * \brief Macros that are used by multiple assembly files + * \author Stefan Kalkowski + * \date 2015-01-30 + */ + +/* + * 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. + */ + +/* core includes */ +.include "spec/arm_v7/macros_support.s" + +/** + * Switch to a given protection domain + * + * \param transit_ttbr0 transitional TTBR0 value, read/write reg + * \param new_cidr new CIDR value, read reg + * \param new_ttbr0 new TTBR0 value, read/write reg + */ +.macro _switch_protection_domain transit_ttbr0, new_cidr, new_ttbr0 + mcr p15, 0, \transit_ttbr0, c2, c0, 0 + isb + mcr p15, 0, \new_cidr, c13, c0, 1 + isb + mcr p15, 0, \new_ttbr0, c2, c0, 0 + isb +.endm diff --git a/repos/base-hw/src/core/include/spec/arm_v7/translation_table.h b/repos/base-hw/src/core/include/spec/cortex_a8/translation_table.h similarity index 67% rename from repos/base-hw/src/core/include/spec/arm_v7/translation_table.h rename to repos/base-hw/src/core/include/spec/cortex_a8/translation_table.h index 677096c9fb..7b7a2fd878 100644 --- a/repos/base-hw/src/core/include/spec/arm_v7/translation_table.h +++ b/repos/base-hw/src/core/include/spec/cortex_a8/translation_table.h @@ -1,22 +1,20 @@ /* - * \brief Armv7 translation table definitions for core - * \author Martin Stein - * \author Stefan Kalkowski - * \date 2012-02-22 + * \brief Translation table definitions for core + * \author Martin Stein + * \author Stefan Kalkowski + * \date 2012-02-22 */ - /* * Copyright (C) 2012-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. */ - #ifndef _TRANSLATION_TABLE_H_ #define _TRANSLATION_TABLE_H_ /* core includes */ -#include +#include constexpr unsigned Genode::Translation::_device_tex() { return 2; } diff --git a/repos/base-hw/src/core/include/spec/cortex_a9/macros.s b/repos/base-hw/src/core/include/spec/cortex_a9/macros.s new file mode 100644 index 0000000000..85efa018f8 --- /dev/null +++ b/repos/base-hw/src/core/include/spec/cortex_a9/macros.s @@ -0,0 +1,40 @@ +/* + * \brief Macros that are used by multiple assembly files + * \author Stefan Kalkowski + * \date 2015-01-30 + */ + +/* + * 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. + */ + +/* core includes */ +.include "spec/arm_v7/macros_support.s" + +/** + * Switch to a given protection domain + * + * \param transit_ttbr0 transitional TTBR0 value, read/write reg + * \param new_cidr new CIDR value, read reg + * \param new_ttbr0 new TTBR0 value, read/write reg + */ +.macro _switch_protection_domain transit_ttbr0, new_cidr, new_ttbr0 + + /* + * FIXME: Fixes instability problems that were observed on the + * PandaBoard only. We neither know why invalidating predictions + * at PD switches is a fix nor wether not doing so is the real + * cause of this instability. + */ + mcr p15, 0, r0, c7, c5, 6 + + mcr p15, 0, \transit_ttbr0, c2, c0, 0 + isb + mcr p15, 0, \new_cidr, c13, c0, 1 + isb + mcr p15, 0, \new_ttbr0, c2, c0, 0 + isb +.endm diff --git a/repos/base-hw/src/core/include/spec/cortex_a9/translation_table.h b/repos/base-hw/src/core/include/spec/cortex_a9/translation_table.h new file mode 100644 index 0000000000..7b7a2fd878 --- /dev/null +++ b/repos/base-hw/src/core/include/spec/cortex_a9/translation_table.h @@ -0,0 +1,21 @@ +/* + * \brief Translation table definitions for core + * \author Martin Stein + * \author Stefan Kalkowski + * \date 2012-02-22 + */ +/* + * Copyright (C) 2012-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. + */ +#ifndef _TRANSLATION_TABLE_H_ +#define _TRANSLATION_TABLE_H_ + +/* core includes */ +#include + +constexpr unsigned Genode::Translation::_device_tex() { return 2; } + +#endif /* _TRANSLATION_TABLE_H_ */ diff --git a/repos/base-hw/src/core/spec/arm/cpu.cc b/repos/base-hw/src/core/spec/arm/cpu.cc new file mode 100644 index 0000000000..e3b76b0f6f --- /dev/null +++ b/repos/base-hw/src/core/spec/arm/cpu.cc @@ -0,0 +1,66 @@ +/* + * \brief CPU driver for core + * \author Martin stein + * \date 2014-07-14 + */ + +/* + * Copyright (C) 2011-2014 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. + */ + +/* core includes */ +#include + +using namespace Genode; + +unsigned Cpu::primary_id() { return 0; } + + +unsigned Cpu::executing_id() { return primary_id(); } + + +addr_t Cpu::Context::translation_table() const { + return Ttbr0::Ba::masked(ttbr0); } + + +void Cpu::Context::translation_table(addr_t const t) { + ttbr0 = Arm::Ttbr0::init(t); } + + +bool Cpu::User_context::in_fault(addr_t & va, addr_t & w) const +{ + switch (cpu_exception) { + + case PREFETCH_ABORT: + { + /* check if fault was caused by a translation miss */ + Ifsr::access_t const fs = Ifsr::Fs::get(Ifsr::read()); + if (fs != Ifsr::section && fs != Ifsr::page) + return false; + + /* fetch fault data */ + w = 0; + va = ip; + return true; + } + case DATA_ABORT: + { + /* check if fault was caused by translation miss */ + Dfsr::access_t const fs = Dfsr::Fs::get(Dfsr::read()); + if (fs != Dfsr::section && fs != Dfsr::page) + return false; + + /* fetch fault data */ + Dfsr::access_t const dfsr = Dfsr::read(); + w = Dfsr::Wnr::get(dfsr); + va = Dfar::read(); + return true; + } + + default: + return false; + }; +} diff --git a/repos/base-hw/src/core/spec/arm_v6/mode_transition.s b/repos/base-hw/src/core/spec/arm_v6/mode_transition.s index e36548f068..c89e115c56 100644 --- a/repos/base-hw/src/core/spec/arm_v6/mode_transition.s +++ b/repos/base-hw/src/core/spec/arm_v6/mode_transition.s @@ -12,7 +12,6 @@ */ /* core includes */ -.include "mode_transition.s" .include "macros.s" diff --git a/repos/base-hw/src/core/spec/arm_v7/mode_transition.s b/repos/base-hw/src/core/spec/arm_v7/mode_transition.s index b243694dcf..bd47095273 100644 --- a/repos/base-hw/src/core/spec/arm_v7/mode_transition.s +++ b/repos/base-hw/src/core/spec/arm_v7/mode_transition.s @@ -13,7 +13,6 @@ */ /* core includes */ -.include "mode_transition.s" .include "macros.s" @@ -84,60 +83,6 @@ .endm -/** - * Override the TTBR0 register - * - * \param val new value, read reg - */ -.macro _write_ttbr0 val - mcr p15, 0, \val, c2, c0, 0 -.endm - - -/** - * Override the CIDR register - * - * \param val new value, read reg - */ -.macro _write_cidr val - mcr p15, 0, \val, c13, c0, 1 -.endm - - -/* - * Invalidate all branch predictors - */ -.macro _bpiall - mcr p15, 0, r0, c7, c5, 6 -.endm - - -/** - * Switch to a given protection domain - * - * \param transit_ttbr0 transitional TTBR0 value, read/write reg - * \param new_cidr new CIDR value, read reg - * \param new_ttbr0 new TTBR0 value, read/write reg - */ -.macro _switch_protection_domain transit_ttbr0, new_cidr, new_ttbr0 - - /* - * FIXME: Fixes instability problems that were observed on the - * PandaBoard only. We neither know why invalidating predictions - * at PD switches is a fix nor wether not doing so is the real - * cause of this instability. - */ - _bpiall - - _write_ttbr0 \transit_ttbr0 - isb - _write_cidr \new_cidr - isb - _write_ttbr0 \new_ttbr0 - isb -.endm - - /** * Save an interrupted user context and switch to the kernel context * diff --git a/repos/base-hw/src/core/spec/exynos5/cpu.cc b/repos/base-hw/src/core/spec/exynos5/cpu.cc index eceb773788..4fea1e1e54 100644 --- a/repos/base-hw/src/core/spec/exynos5/cpu.cc +++ b/repos/base-hw/src/core/spec/exynos5/cpu.cc @@ -1,6 +1,7 @@ /* * \brief CPU driver for core * \author Martin stein + * \author Stefan Kalkowski * \date 2011-11-03 */ @@ -19,4 +20,48 @@ using namespace Genode; unsigned Cpu::executing_id() { return Mpidr::Aff_0::get(Mpidr::read()); } + unsigned Cpu::primary_id() { return Board::PRIMARY_MPIDR_AFF_0; } + + +addr_t Cpu::Context::translation_table() const { return ttbr0; } + + +void Cpu::Context::translation_table(addr_t const t) { ttbr0 = t; } + + +bool Cpu::User_context::in_fault(addr_t & va, addr_t & w) const +{ + switch (cpu_exception) { + + case PREFETCH_ABORT: + { + /* check if fault was caused by a translation miss */ + Ifsr::access_t const fs = Ifsr::Fs::get(Ifsr::read()); + if ((fs & 0b11100) != 0b100) + return false; + + /* fetch fault data */ + w = 0; + va = ip; + return true; + } + + case DATA_ABORT: + { + /* check if fault was caused by translation miss */ + Dfsr::access_t const fs = Dfsr::Fs::get(Dfsr::read()); + if ((fs & 0b11100) != 0b100) + return false; + + /* fetch fault data */ + Dfsr::access_t const dfsr = Dfsr::read(); + w = Dfsr::Wnr::get(dfsr); + va = Dfar::read(); + return true; + } + + default: + return false; + }; +}