mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-24 15:56:41 +00:00
base_hw: Use TLB-specific 'struct Page_flags'.
'Page_flags' maps application-specific memory attributes to the TLB-specific memory attributes. Thereby it avoids functions with lots of parameters, by declaring appropriate bitfields on a single POD value.
This commit is contained in:
parent
47690b8802
commit
4723b08322
@ -31,6 +31,13 @@ class Tlb : public Arm_v6::Section_table
|
|||||||
void * operator new (Genode::size_t, void * p) { return p; }
|
void * operator new (Genode::size_t, void * p) { return p; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Board specific mapping attributes
|
||||||
|
*/
|
||||||
|
struct Page_flags : Arm::Page_flags { };
|
||||||
|
|
||||||
|
typedef Arm::page_flags_t page_flags_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TLB of core
|
* TLB of core
|
||||||
*
|
*
|
||||||
@ -42,11 +49,8 @@ class Core_tlb : public Tlb
|
|||||||
|
|
||||||
Core_tlb()
|
Core_tlb()
|
||||||
{
|
{
|
||||||
/* map RAM */
|
map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0);
|
||||||
translate_dpm_off(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0, 1);
|
map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1);
|
||||||
|
|
||||||
/* map MMIO */
|
|
||||||
translate_dpm_off(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1, 0);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,6 +22,45 @@ namespace Arm
|
|||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map app-specific mem attributes to a TLB-specific POD
|
||||||
|
*/
|
||||||
|
struct Page_flags : Register<8>
|
||||||
|
{
|
||||||
|
struct W : Bitfield<0, 1> { }; /* writeable */
|
||||||
|
struct X : Bitfield<1, 1> { }; /* executable */
|
||||||
|
struct K : Bitfield<2, 1> { }; /* privileged */
|
||||||
|
struct G : Bitfield<3, 1> { }; /* global */
|
||||||
|
struct D : Bitfield<4, 1> { }; /* device */
|
||||||
|
struct C : Bitfield<5, 1> { }; /* cacheable */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create flag POD for Genode pagers
|
||||||
|
*/
|
||||||
|
static access_t
|
||||||
|
resolve_and_wait_for_fault(bool const writeable,
|
||||||
|
bool const write_combined,
|
||||||
|
bool const io_mem) {
|
||||||
|
return W::bits(writeable) | X::bits(1) | K::bits(0) | G::bits(0) |
|
||||||
|
D::bits(io_mem) | C::bits(!write_combined & !io_mem); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create flag POD for kernel when it creates the core space
|
||||||
|
*/
|
||||||
|
static access_t map_core_area(bool const io_mem) {
|
||||||
|
return W::bits(1) | X::bits(1) | K::bits(0) | G::bits(0) |
|
||||||
|
D::bits(io_mem) | C::bits(!io_mem); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create flag POD for the mode transition region
|
||||||
|
*/
|
||||||
|
static access_t mode_transition() {
|
||||||
|
return W::bits(1) | X::bits(1) | K::bits(1) | G::bits(1) |
|
||||||
|
D::bits(0) | C::bits(1); }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Page_flags::access_t page_flags_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if 'p' is aligned to 1 << 'alignm_log2'
|
* Check if 'p' is aligned to 1 << 'alignm_log2'
|
||||||
*/
|
*/
|
||||||
@ -65,11 +104,10 @@ namespace Arm
|
|||||||
* \return descriptor value with requested perms and the rest left zero
|
* \return descriptor value with requested perms and the rest left zero
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static typename T::access_t access_permission_bits(bool const w,
|
static typename T::access_t
|
||||||
bool const x,
|
access_permission_bits(page_flags_t const flags)
|
||||||
bool const k)
|
|
||||||
{
|
{
|
||||||
/* lookup table for AP bitfield values according to 'w' and 'k' */
|
/* lookup table for AP bitfield values according to 'w' and 'k' flag */
|
||||||
typedef typename T::Ap_1_0 Ap_1_0;
|
typedef typename T::Ap_1_0 Ap_1_0;
|
||||||
typedef typename T::Ap_2 Ap_2;
|
typedef typename T::Ap_2 Ap_2;
|
||||||
static typename T::access_t const ap_bits[2][2] = {{
|
static typename T::access_t const ap_bits[2][2] = {{
|
||||||
@ -85,9 +123,10 @@ namespace Arm
|
|||||||
Ap_1_0::bits(Ap_1_0::USER_NO_ACCESS) | /* wk */
|
Ap_1_0::bits(Ap_1_0::USER_NO_ACCESS) | /* wk */
|
||||||
Ap_2::bits(Ap_2::KERNEL_RW_OR_NO_ACCESS) }
|
Ap_2::bits(Ap_2::KERNEL_RW_OR_NO_ACCESS) }
|
||||||
};
|
};
|
||||||
/* combine XN and AP bitfield values according to 'w', 'x' and 'k' */
|
/* combine XN and AP bitfield values according to the flags */
|
||||||
typedef typename T::Xn Xn;
|
typedef typename T::Xn Xn;
|
||||||
return Xn::bits(!x) | ap_bits[w][k];
|
return Xn::bits(!Page_flags::X::get(flags)) |
|
||||||
|
ap_bits[Page_flags::W::get(flags)][Page_flags::K::get(flags)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,7 +141,7 @@ namespace Arm
|
|||||||
* Memory region attributes for the translation descriptor 'T'
|
* Memory region attributes for the translation descriptor 'T'
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static typename T::access_t memory_region_attr(bool const d, bool const c)
|
static typename T::access_t memory_region_attr(page_flags_t const flags)
|
||||||
{
|
{
|
||||||
typedef typename T::Tex Tex;
|
typedef typename T::Tex Tex;
|
||||||
typedef typename T::C C;
|
typedef typename T::C C;
|
||||||
@ -111,9 +150,11 @@ namespace Arm
|
|||||||
/*
|
/*
|
||||||
* FIXME: upgrade to write-back & write-allocate when !d & c
|
* FIXME: upgrade to write-back & write-allocate when !d & c
|
||||||
*/
|
*/
|
||||||
if(d) return Tex::bits(2) | C::bits(0) | B::bits(0);
|
if(Page_flags::D::get(flags))
|
||||||
|
return Tex::bits(2) | C::bits(0) | B::bits(0);
|
||||||
if(cache_support()) {
|
if(cache_support()) {
|
||||||
if(c) return Tex::bits(6) | C::bits(1) | B::bits(0);
|
if(Page_flags::C::get(flags))
|
||||||
|
return Tex::bits(6) | C::bits(1) | B::bits(0);
|
||||||
return Tex::bits(4) | C::bits(0) | B::bits(0);
|
return Tex::bits(4) | C::bits(0) | B::bits(0);
|
||||||
}
|
}
|
||||||
return Tex::bits(4) | C::bits(0) | B::bits(0);
|
return Tex::bits(4) | C::bits(0) | B::bits(0);
|
||||||
@ -253,16 +294,13 @@ namespace Arm
|
|||||||
/**
|
/**
|
||||||
* Compose descriptor value
|
* Compose descriptor value
|
||||||
*/
|
*/
|
||||||
static access_t create(bool const w, bool const x,
|
static access_t create(page_flags_t const flags,
|
||||||
bool const k, bool const g,
|
|
||||||
bool const d, bool const c,
|
|
||||||
addr_t const pa)
|
addr_t const pa)
|
||||||
{
|
{
|
||||||
access_t v = access_permission_bits<Small_page>(w, x, k) |
|
access_t v = access_permission_bits<Small_page>(flags) |
|
||||||
memory_region_attr<Small_page>(d, c) |
|
memory_region_attr<Small_page>(flags) |
|
||||||
Ng::bits(!g) |
|
Ng::bits(!Page_flags::G::get(flags)) |
|
||||||
S::bits(0) |
|
S::bits(0) | Pa_31_12::masked(pa);
|
||||||
Pa_31_12::masked(pa);
|
|
||||||
Descriptor::type(v, Descriptor::SMALL_PAGE);
|
Descriptor::type(v, Descriptor::SMALL_PAGE);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@ -335,12 +373,7 @@ namespace Arm
|
|||||||
* \param pa base of the physical backing store
|
* \param pa base of the physical backing store
|
||||||
* \param size_log2 log2(Size of the translated region),
|
* \param size_log2 log2(Size of the translated region),
|
||||||
* must be supported by this table
|
* must be supported by this table
|
||||||
* \param w see 'Section_table::insert_translation'
|
* \param flags mapping flags
|
||||||
* \param x see 'Section_table::insert_translation'
|
|
||||||
* \param k see 'Section_table::insert_translation'
|
|
||||||
* \param g see 'Section_table::insert_translation'
|
|
||||||
* \param d see 'Section_table::insert_translation'
|
|
||||||
* \param c see 'Section_table::insert_translation'
|
|
||||||
*
|
*
|
||||||
* This method overrides an existing translation in case
|
* This method overrides an existing translation in case
|
||||||
* that it spans the the same virtual range and is not
|
* that it spans the the same virtual range and is not
|
||||||
@ -348,9 +381,7 @@ namespace Arm
|
|||||||
*/
|
*/
|
||||||
void insert_translation(addr_t const vo, addr_t const pa,
|
void insert_translation(addr_t const vo, addr_t const pa,
|
||||||
unsigned long const size_log2,
|
unsigned long const size_log2,
|
||||||
bool const w, bool const x,
|
page_flags_t const flags)
|
||||||
bool const k, bool const g,
|
|
||||||
bool const d, bool const c)
|
|
||||||
{
|
{
|
||||||
/* validate virtual address */
|
/* validate virtual address */
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
@ -363,7 +394,7 @@ namespace Arm
|
|||||||
{
|
{
|
||||||
/* compose new descriptor value */
|
/* compose new descriptor value */
|
||||||
Descriptor::access_t const entry =
|
Descriptor::access_t const entry =
|
||||||
Small_page::create(w, x, k, g, d, c, pa);
|
Small_page::create(flags, pa);
|
||||||
|
|
||||||
/* check if we can we write to the targeted entry */
|
/* check if we can we write to the targeted entry */
|
||||||
if (Descriptor::valid(_entries[i]))
|
if (Descriptor::valid(_entries[i]))
|
||||||
@ -614,16 +645,13 @@ namespace Arm
|
|||||||
/**
|
/**
|
||||||
* Compose descriptor value
|
* Compose descriptor value
|
||||||
*/
|
*/
|
||||||
static access_t create(bool const w, bool const x,
|
static access_t create(page_flags_t const flags,
|
||||||
bool const k, bool const g,
|
|
||||||
bool const d, bool const c,
|
|
||||||
addr_t const pa)
|
addr_t const pa)
|
||||||
{
|
{
|
||||||
access_t v = access_permission_bits<Section>(w, x, k) |
|
access_t v = access_permission_bits<Section>(flags) |
|
||||||
memory_region_attr<Section>(d, c) |
|
memory_region_attr<Section>(flags) |
|
||||||
Domain::bits(DOMAIN) |
|
Domain::bits(DOMAIN) | S::bits(0) |
|
||||||
S::bits(0) |
|
Ng::bits(!Page_flags::G::get(flags)) |
|
||||||
Ng::bits(!g) |
|
|
||||||
Pa_31_20::masked(pa);
|
Pa_31_20::masked(pa);
|
||||||
Descriptor::type(v, Descriptor::SECTION);
|
Descriptor::type(v, Descriptor::SECTION);
|
||||||
return v;
|
return v;
|
||||||
@ -693,17 +721,7 @@ namespace Arm
|
|||||||
* region represented by this table
|
* region represented by this table
|
||||||
* \param pa base of the physical backing store
|
* \param pa base of the physical backing store
|
||||||
* \param size_log2 size log2 of the translated region
|
* \param size_log2 size log2 of the translated region
|
||||||
* \param w if one can write trough this translation
|
* \param flags mapping flags
|
||||||
* \param x if one can execute trough this translation
|
|
||||||
* \param k If set to 1, the given permissions apply
|
|
||||||
* in kernel mode, while in user mode this
|
|
||||||
* translations grants no type of access.
|
|
||||||
* If set to 0, the given permissions apply
|
|
||||||
* in user mode, while in kernel mode this
|
|
||||||
* translation grants any type of access.
|
|
||||||
* \param g if the translation applies to all spaces
|
|
||||||
* \param d wether 'pa' addresses device IO-memory
|
|
||||||
* \param c if access shall be cacheable
|
|
||||||
* \param extra_space If > 0, it must point to a portion of
|
* \param extra_space If > 0, it must point to a portion of
|
||||||
* size-aligned memory space wich may be used
|
* size-aligned memory space wich may be used
|
||||||
* furthermore by the table for the incurring
|
* furthermore by the table for the incurring
|
||||||
@ -727,9 +745,7 @@ namespace Arm
|
|||||||
template <typename ST>
|
template <typename ST>
|
||||||
unsigned long insert_translation(addr_t const vo, addr_t const pa,
|
unsigned long insert_translation(addr_t const vo, addr_t const pa,
|
||||||
unsigned long const size_log2,
|
unsigned long const size_log2,
|
||||||
bool const w, bool const x,
|
page_flags_t const flags,
|
||||||
bool const k, bool const g,
|
|
||||||
bool const d, bool const c,
|
|
||||||
ST * const st,
|
ST * const st,
|
||||||
void * const extra_space = 0)
|
void * const extra_space = 0)
|
||||||
{
|
{
|
||||||
@ -768,14 +784,14 @@ namespace Arm
|
|||||||
|
|
||||||
/* insert translation */
|
/* insert translation */
|
||||||
pt->insert_translation(vo - Section::Pa_31_20::masked(vo),
|
pt->insert_translation(vo - Section::Pa_31_20::masked(vo),
|
||||||
pa, size_log2, w, x, k, g, d, c);
|
pa, size_log2, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (size_log2 == Section::VIRT_SIZE_LOG2)
|
if (size_log2 == Section::VIRT_SIZE_LOG2)
|
||||||
{
|
{
|
||||||
/* compose section descriptor */
|
/* compose section descriptor */
|
||||||
Descriptor::access_t const entry =
|
Descriptor::access_t const entry =
|
||||||
Section::create(w, x, k, g, d, c, pa, st);
|
Section::create(flags, pa, st);
|
||||||
|
|
||||||
/* check if we can we write to the targeted entry */
|
/* check if we can we write to the targeted entry */
|
||||||
if (Descriptor::valid(_entries[i]))
|
if (Descriptor::valid(_entries[i]))
|
||||||
@ -916,23 +932,28 @@ namespace Arm
|
|||||||
*
|
*
|
||||||
* \param vo virtual offset within this table
|
* \param vo virtual offset within this table
|
||||||
* \param s area size
|
* \param s area size
|
||||||
* \param d wether area maps device IO memory
|
* \param flags mapping flags
|
||||||
* \param c wether area maps cacheable memory
|
|
||||||
*/
|
*/
|
||||||
template <typename ST>
|
template <typename ST>
|
||||||
void translate_dpm_off(addr_t vo, size_t s,
|
void map_core_area(addr_t vo, size_t s, bool io_mem, ST * st)
|
||||||
bool const d, bool const c, ST * st)
|
|
||||||
{
|
{
|
||||||
|
/* initialize parameters */
|
||||||
|
page_flags_t const flags = Page_flags::map_core_area(io_mem);
|
||||||
unsigned tsl2 = translation_size_l2(vo, s);
|
unsigned tsl2 = translation_size_l2(vo, s);
|
||||||
size_t ts = 1 << tsl2;
|
size_t ts = 1 << tsl2;
|
||||||
while (1) {
|
|
||||||
if(st->insert_translation(vo, vo, tsl2, 1,1,0,0,d,c)) {
|
/* walk through the area and map all offsets */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* map current offset without displacement */
|
||||||
|
if(st->insert_translation(vo, vo, tsl2, flags)) {
|
||||||
PDBG("Displacement not permitted");
|
PDBG("Displacement not permitted");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* update parameters for next round or exit */
|
||||||
vo += ts;
|
vo += ts;
|
||||||
s = ts < s ? s - ts : 0;
|
s = ts < s ? s - ts : 0;
|
||||||
if (!s) break;
|
if (!s) return;
|
||||||
tsl2 = translation_size_l2(vo, s);
|
tsl2 = translation_size_l2(vo, s);
|
||||||
ts = 1 << tsl2;
|
ts = 1 << tsl2;
|
||||||
}
|
}
|
||||||
|
@ -53,14 +53,10 @@ namespace Arm_v6
|
|||||||
/**
|
/**
|
||||||
* Compose descriptor value
|
* Compose descriptor value
|
||||||
*/
|
*/
|
||||||
static access_t create(bool const w, bool const x,
|
static access_t create(Arm::page_flags_t const flags,
|
||||||
bool const k, bool const g,
|
addr_t const pa, Section_table *)
|
||||||
bool const d, bool const c,
|
|
||||||
addr_t const pa,
|
|
||||||
Section_table *)
|
|
||||||
{
|
{
|
||||||
return Arm::Section_table::Section::create(w, x, k, g,
|
return Arm::Section_table::Section::create(flags, pa) |
|
||||||
d, c, pa) |
|
|
||||||
P::bits(0);
|
P::bits(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -70,33 +66,25 @@ namespace Arm_v6
|
|||||||
*
|
*
|
||||||
* For details see 'Arm::Section_table::insert_translation'
|
* For details see 'Arm::Section_table::insert_translation'
|
||||||
*/
|
*/
|
||||||
unsigned long insert_translation(addr_t const vo, addr_t const pa,
|
unsigned long
|
||||||
|
insert_translation(addr_t const vo, addr_t const pa,
|
||||||
unsigned long const size_log2,
|
unsigned long const size_log2,
|
||||||
bool const w, bool const x,
|
Arm::page_flags_t const flags,
|
||||||
bool const k, bool const g,
|
void * const extra_space = 0) {
|
||||||
bool const d, bool const c,
|
|
||||||
void * const extra_space = 0)
|
|
||||||
{
|
|
||||||
return Arm::Section_table::
|
return Arm::Section_table::
|
||||||
insert_translation<Section_table>(vo, pa, size_log2, w,
|
insert_translation<Section_table>(vo, pa, size_log2, flags,
|
||||||
x, k, g, d, c, this,
|
this, extra_space); }
|
||||||
extra_space);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert translations for given area, do not permit displacement
|
* Insert translations for given area, do not permit displacement
|
||||||
*
|
*
|
||||||
* \param vo virtual offset within this table
|
* \param vo virtual offset within this table
|
||||||
* \param s area size
|
* \param s area size
|
||||||
* \param d wether area maps device IO memory
|
* \param io_mem wether the area maps MMIO
|
||||||
* \param c wether area maps cacheable memory
|
|
||||||
*/
|
*/
|
||||||
void translate_dpm_off(addr_t vo, size_t s,
|
void map_core_area(addr_t vo, size_t s, bool const io_mem) {
|
||||||
bool const d, bool const c)
|
Arm::Section_table::map_core_area<Section_table>(vo, s, io_mem,
|
||||||
{
|
this); }
|
||||||
Arm::Section_table::
|
|
||||||
translate_dpm_off<Section_table>(vo, s, d, c, this);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,13 +57,11 @@ namespace Arm_v7
|
|||||||
/**
|
/**
|
||||||
* Compose descriptor value
|
* Compose descriptor value
|
||||||
*/
|
*/
|
||||||
static access_t create(bool const w, bool const x,
|
static access_t create(Arm::page_flags_t const flags,
|
||||||
bool const k, bool const g,
|
|
||||||
bool const d, bool const c,
|
|
||||||
addr_t const pa,
|
addr_t const pa,
|
||||||
Section_table * const st)
|
Section_table * const st)
|
||||||
{
|
{
|
||||||
return Arm::Section_table::Section::create(w, x, k, g, d, c, pa) |
|
return Arm::Section_table::Section::create(flags, pa) |
|
||||||
Ns::bits(!st->secure());
|
Ns::bits(!st->secure());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -85,33 +83,25 @@ namespace Arm_v7
|
|||||||
*
|
*
|
||||||
* For details see 'Arm::Section_table::insert_translation'
|
* For details see 'Arm::Section_table::insert_translation'
|
||||||
*/
|
*/
|
||||||
unsigned long insert_translation(addr_t const vo, addr_t const pa,
|
unsigned long
|
||||||
|
insert_translation(addr_t const vo, addr_t const pa,
|
||||||
unsigned long const size_log2,
|
unsigned long const size_log2,
|
||||||
bool const w, bool const x,
|
Arm::page_flags_t const flags,
|
||||||
bool const k, bool const g,
|
void * const extra_space = 0) {
|
||||||
bool const d, bool const c,
|
|
||||||
void * const extra_space = 0)
|
|
||||||
{
|
|
||||||
return Arm::Section_table::
|
return Arm::Section_table::
|
||||||
insert_translation<Section_table>(vo, pa, size_log2, w,
|
insert_translation<Section_table>(vo, pa, size_log2, flags,
|
||||||
x, k, g, d, c, this,
|
this, extra_space); }
|
||||||
extra_space);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert translations for given area, do not permit displacement
|
* Insert translations for given area, do not permit displacement
|
||||||
*
|
*
|
||||||
* \param vo virtual offset within this table
|
* \param vo virtual offset within this table
|
||||||
* \param s area size
|
* \param s area size
|
||||||
* \param d wether area maps device IO memory
|
* \param io_mem wether the area maps MMIO
|
||||||
* \param c wether area maps cacheable memory
|
|
||||||
*/
|
*/
|
||||||
void translate_dpm_off(addr_t vo, size_t s,
|
void map_core_area(addr_t vo, size_t s, bool const io_mem) {
|
||||||
bool const d, bool const c)
|
Arm::Section_table::map_core_area<Section_table>(vo, s, io_mem,
|
||||||
{
|
this); }
|
||||||
Arm::Section_table::
|
|
||||||
translate_dpm_off<Section_table>(vo, s, d, c, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
** Accessors **
|
** Accessors **
|
||||||
|
@ -801,12 +801,11 @@ namespace Kernel
|
|||||||
Pd(Tlb * const t) : _tlb(t)
|
Pd(Tlb * const t) : _tlb(t)
|
||||||
{
|
{
|
||||||
/* try to add translation for mode transition region */
|
/* try to add translation for mode transition region */
|
||||||
enum Mtc_attributes { W = 1, X = 1, K = 1, G = 1, D = 0, C = 1 };
|
page_flags_t const flags = Page_flags::mode_transition();
|
||||||
unsigned const slog2 =
|
unsigned const slog2 =
|
||||||
tlb()->insert_translation(mtc()->VIRT_BASE,
|
tlb()->insert_translation(mtc()->VIRT_BASE,
|
||||||
mtc()->phys_base(),
|
mtc()->phys_base(),
|
||||||
mtc()->SIZE_LOG2,
|
mtc()->SIZE_LOG2, flags);
|
||||||
W, X, K, G, D, C);
|
|
||||||
|
|
||||||
/* extra space needed to translate mode transition region */
|
/* extra space needed to translate mode transition region */
|
||||||
if (slog2)
|
if (slog2)
|
||||||
@ -824,8 +823,7 @@ namespace Kernel
|
|||||||
/* translate mode transition region globally */
|
/* translate mode transition region globally */
|
||||||
tlb()->insert_translation(mtc()->VIRT_BASE,
|
tlb()->insert_translation(mtc()->VIRT_BASE,
|
||||||
mtc()->phys_base(),
|
mtc()->phys_base(),
|
||||||
mtc()->SIZE_LOG2,
|
mtc()->SIZE_LOG2, flags,
|
||||||
W, X, K, G, D, C,
|
|
||||||
(void *)aligned_es);
|
(void *)aligned_es);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,13 @@ class Tlb : public Arm_v7::Section_table
|
|||||||
void * operator new (Genode::size_t, void * p) { return p; }
|
void * operator new (Genode::size_t, void * p) { return p; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Board specific mapping attributes
|
||||||
|
*/
|
||||||
|
struct Page_flags : Arm::Page_flags { };
|
||||||
|
|
||||||
|
typedef Arm::page_flags_t page_flags_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TLB of core
|
* TLB of core
|
||||||
*
|
*
|
||||||
@ -45,13 +52,9 @@ class Core_tlb : public Tlb
|
|||||||
Core_tlb()
|
Core_tlb()
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0);
|
||||||
/* map RAM */
|
map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1);
|
||||||
translate_dpm_off(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0, 1);
|
map_core_area(Board::MMIO_1_BASE, Board::MMIO_1_SIZE, 1);
|
||||||
|
|
||||||
/* map MMIO */
|
|
||||||
translate_dpm_off(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1, 0);
|
|
||||||
translate_dpm_off(Board::MMIO_1_BASE, Board::MMIO_1_SIZE, 1, 0);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,6 +33,13 @@ class Tlb : public Arm_v7::Section_table
|
|||||||
void * operator new (Genode::size_t, void * p) { return p; }
|
void * operator new (Genode::size_t, void * p) { return p; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Board specific mapping attributes
|
||||||
|
*/
|
||||||
|
struct Page_flags : Arm::Page_flags { };
|
||||||
|
|
||||||
|
typedef Arm::page_flags_t page_flags_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TLB of core
|
* TLB of core
|
||||||
*
|
*
|
||||||
@ -45,14 +52,10 @@ class Core_tlb : public Tlb
|
|||||||
Core_tlb()
|
Core_tlb()
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0);
|
||||||
/* map RAM */
|
map_core_area(Board::RAM_1_BASE, Board::RAM_1_SIZE, 0);
|
||||||
translate_dpm_off(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0, 1);
|
map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1);
|
||||||
translate_dpm_off(Board::RAM_1_BASE, Board::RAM_1_SIZE, 0, 1);
|
map_core_area(Board::MMIO_1_BASE, Board::MMIO_1_SIZE, 1);
|
||||||
|
|
||||||
/* map MMIO */
|
|
||||||
translate_dpm_off(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1, 0);
|
|
||||||
translate_dpm_off(Board::MMIO_1_BASE, Board::MMIO_1_SIZE, 1, 0);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,16 +57,17 @@ void Ipc_pager::resolve_and_wait_for_fault()
|
|||||||
/* valid mapping? */
|
/* valid mapping? */
|
||||||
assert(_mapping.valid());
|
assert(_mapping.valid());
|
||||||
|
|
||||||
/* do we need extra space to resolve pagefault? */
|
/* prepare mapping */
|
||||||
Tlb * const tlb = _pagefault.tlb;
|
Tlb * const tlb = _pagefault.tlb;
|
||||||
enum { X = 1, K = 0, G = 0 };
|
page_flags_t const flags =
|
||||||
bool c = !_mapping.write_combined && !_mapping.io_mem;
|
Page_flags::resolve_and_wait_for_fault(_mapping.writable,
|
||||||
bool d = _mapping.io_mem;
|
_mapping.write_combined,
|
||||||
|
_mapping.io_mem);
|
||||||
|
|
||||||
/* insert mapping into TLB */
|
/* insert mapping into TLB */
|
||||||
unsigned sl2 = tlb->insert_translation(_mapping.virt_address,
|
unsigned sl2;
|
||||||
_mapping.phys_address, _mapping.size_log2,
|
sl2 = tlb->insert_translation(_mapping.virt_address, _mapping.phys_address,
|
||||||
_mapping.writable, X, K, G, d, c);
|
_mapping.size_log2, flags);
|
||||||
if (sl2)
|
if (sl2)
|
||||||
{
|
{
|
||||||
/* try to get some natural aligned space */
|
/* try to get some natural aligned space */
|
||||||
@ -76,8 +77,7 @@ void Ipc_pager::resolve_and_wait_for_fault()
|
|||||||
/* try to translate again with extra space */
|
/* try to translate again with extra space */
|
||||||
sl2 = tlb->insert_translation(_mapping.virt_address,
|
sl2 = tlb->insert_translation(_mapping.virt_address,
|
||||||
_mapping.phys_address,
|
_mapping.phys_address,
|
||||||
_mapping.size_log2,
|
_mapping.size_log2, flags, space);
|
||||||
_mapping.writable, X, K, G, d, c, space);
|
|
||||||
assert(!sl2);
|
assert(!sl2);
|
||||||
}
|
}
|
||||||
/* try to wake up faulter */
|
/* try to wake up faulter */
|
||||||
|
@ -33,28 +33,34 @@ class Tlb : public Arm_v7::Section_table
|
|||||||
void * operator new (Genode::size_t, void * p) { return p; }
|
void * operator new (Genode::size_t, void * p) { return p; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Board specific mapping attributes
|
||||||
|
*/
|
||||||
|
struct Page_flags : Arm::Page_flags { };
|
||||||
|
|
||||||
|
typedef Arm::page_flags_t page_flags_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TLB of core
|
* TLB of core
|
||||||
*
|
|
||||||
* Must ensure that core never gets a pagefault.
|
|
||||||
*/
|
*/
|
||||||
class Core_tlb : public Tlb
|
class Core_tlb : public Tlb
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* Must ensure that core never gets a pagefault.
|
||||||
|
*/
|
||||||
Core_tlb()
|
Core_tlb()
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0);
|
||||||
/* map RAM */
|
map_core_area(Board::RAM_1_BASE, Board::RAM_1_SIZE, 0);
|
||||||
translate_dpm_off(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0, 1);
|
map_core_area(Board::RAM_2_BASE, Board::RAM_2_SIZE, 0);
|
||||||
translate_dpm_off(Board::RAM_1_BASE, Board::RAM_1_SIZE, 0, 1);
|
map_core_area(Board::RAM_3_BASE, Board::RAM_3_SIZE, 0);
|
||||||
translate_dpm_off(Board::RAM_2_BASE, Board::RAM_2_SIZE, 0, 1);
|
map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1);
|
||||||
translate_dpm_off(Board::RAM_3_BASE, Board::RAM_3_SIZE, 0, 1);
|
map_core_area(Board::MMIO_1_BASE, Board::MMIO_1_SIZE, 1);
|
||||||
|
|
||||||
/* map MMIO */
|
|
||||||
translate_dpm_off(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1, 0);
|
|
||||||
translate_dpm_off(Board::MMIO_1_BASE, Board::MMIO_1_SIZE, 1, 0);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user