hw: set TTBR0 according to CPU facilities

Fixes #1195
This commit is contained in:
Stefan Kalkowski 2014-08-27 11:57:16 +02:00 committed by Christian Helmuth
parent e9032904a3
commit f0fae2a5f2
13 changed files with 43 additions and 92 deletions

View File

@ -9,7 +9,6 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/arm_v6
# add C++ sources
SRC_CC += cpu.cc
SRC_CC += spec/arm_v6/cpu.cc
# add assembly sources
SRC_S += spec/arm_v6/mode_transition.s

View File

@ -7,9 +7,6 @@
# 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

View File

@ -28,8 +28,8 @@ namespace Genode
static void prepare_kernel() { }
static void secondary_processors_ip(void * const ip) { }
};
static bool is_smp() { return false; }
};
}
#endif /* _BOARD_H_ */

View File

@ -123,7 +123,22 @@ class Genode::Arm
*/
struct Ttbr0 : Register<32>
{
struct Ba : Bitfield<14, 18> { }; /* base */
enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 };
struct C : Bitfield<0,1> { }; /* inner cacheable */
struct S : Bitfield<1,1> { }; /* shareable */
struct Rgn : Bitfield<3,2> { }; /* outer cachable mode */
struct Nos : Bitfield<5,1> { }; /* not outer shareable */
struct Ba : Bitfield<14, 18> { }; /* translation table base */
/*************************************
* with multiprocessing extension **
*************************************/
struct Irgn_1 : Bitfield<0,1> { };
struct Irgn_0 : Bitfield<6,1> { };
struct Irgn : Bitset_2<Irgn_0, Irgn_1> { }; /* inner cache mode */
static void write(access_t const v) {
asm volatile ("mcr p15, 0, %0, c2, c0, 0" :: "r" (v) : ); }
@ -134,6 +149,21 @@ class Genode::Arm
asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r" (v) :: );
return v;
}
/**
* Return initialized value
*
* \param table base of targeted translation table
*/
static access_t init(addr_t const table)
{
access_t v = Ba::masked((addr_t)table);
Rgn::set(v, CACHEABLE);
S::set(v, Board::is_smp() ? 1 : 0);
if (Board::is_smp()) Irgn::set(v, CACHEABLE);
else C::set(v, 1);
return v;
}
};
/**
@ -318,7 +348,8 @@ class Genode::Arm
/**
* Assign translation-table base 'table'
*/
void translation_table(addr_t const table);
void translation_table(addr_t const table) {
ttbr0 = Arm::Ttbr0::init(table); }
/**
* Assign protection domain
@ -477,11 +508,6 @@ class Genode::Arm
base &= line_align_mask;
for (; base < top; base += line_size) { Icimvau::write(base); }
}
/**
* Return true if the CPU supports multiple cores
*/
static bool is_smp() { return PROCESSORS > 1; }
};
#endif /* _SPEC__ARM__CPU_SUPPORT_H_ */

View File

@ -62,7 +62,7 @@ class Genode::Translation
_create(Page_flags const & f, addr_t const pa)
{
typename T::access_t v = T::Pa::masked(pa);
T::S::set(v, Cpu::is_smp());
T::S::set(v, Board::is_smp());
T::Ng::set(v, !f.global);
T::Xn::set(v, !f.executable);
if (f.device) { T::Tex::set(v, _device_tex()); }

View File

@ -101,20 +101,6 @@ class Genode::Cpu : public Arm
}
};
/**
* Translation table base register 0
*/
struct Ttbr0 : Arm::Ttbr0
{
/**
* Return initialized value
*
* \param table base of targeted translation table
*/
static access_t init(addr_t const table) {
return Ba::masked(table); }
};
/**
* If page descriptor bits [13:12] are restricted
*/
@ -155,7 +141,7 @@ class Genode::Cpu : public Arm
*/
static void tlb_insertions() { flush_tlb(); }
static void start_secondary_processors(void *) { assert(!is_smp()); }
static void start_secondary_processors(void *) { assert(!Board::is_smp()); }
/**
* Return wether to retry an undefined user instruction after this call

View File

@ -218,28 +218,6 @@ class Genode::Arm_v7 : public Arm
public:
/**
* Translation table base register 0
*/
struct Ttbr0 : Arm::Ttbr0
{
struct Irgn_1 : Bitfield<0, 1> { }; /* inner cache attr */
struct Rgn : Bitfield<3, 2> { }; /* outer cache attr */
struct Irgn_0 : Bitfield<6, 1> { }; /* inner cache attr */
struct Irgn : Bitset_2<Irgn_0, Irgn_1> { }; /* inner cache attr */
/**
* Return value initialized with translation table 'table'
*/
static access_t init(addr_t const table)
{
access_t v = Ba::masked(table);
Irgn::set(v, 1);
Rgn::set(v, 1);
return v;
}
};
/**
* Invalidate all branch predictions
*/
@ -318,7 +296,7 @@ class Genode::Arm_v7 : public Arm
*/
static void start_secondary_processors(void * const ip)
{
if (!is_smp()) { return; }
if (!(PROCESSORS > 1)) { return; }
Board::secondary_processors_ip(ip);
data_synchronization_barrier();
asm volatile ("sev\n");

View File

@ -36,6 +36,8 @@ namespace Genode
{
*(void * volatile *)IRAM_BASE = ip;
}
static bool is_smp() { return true; }
};
}

View File

@ -95,6 +95,7 @@ namespace Genode
static void outer_cache_invalidate() { }
static void outer_cache_flush() { }
static bool is_smp() { return false; }
};
}

View File

@ -102,6 +102,7 @@ namespace Imx53
* Tell secondary processors where to start execution from
*/
static void secondary_processors_ip(void *) { }
static bool is_smp() { return false; }
};
}

View File

@ -113,6 +113,7 @@ namespace Genode
static void prepare_kernel();
static void secondary_processors_ip(void * const ip) { }
static bool is_smp() { return true; }
};
}

View File

@ -1,20 +0,0 @@
/*
* \brief CPU driver for core
* \author Martin stein
* \date 2014-08-06
*/
/*
* 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.
*/
/* core includes */
#include <cpu.h>
using namespace Genode;
void Arm::Context::translation_table(addr_t const table) {
ttbr0 = Cpu::Ttbr0::init(table); }

View File

@ -1,20 +0,0 @@
/*
* \brief CPU driver for core
* \author Martin stein
* \date 2014-08-06
*/
/*
* 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.
*/
/* core includes */
#include <cpu.h>
using namespace Genode;
void Arm::Context::translation_table(addr_t const table) {
ttbr0 = Arm_v7::Ttbr0::init(table); }