From 4723b0832232bc9e7d3089f6446e2bb35536b70c Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Fri, 9 Nov 2012 14:36:19 +0100 Subject: [PATCH] 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. --- base-hw/src/core/imx31/tlb.h | 14 +- base-hw/src/core/include/arm/section_table.h | 147 ++++++++++-------- .../src/core/include/arm/v6/section_table.h | 44 ++---- .../src/core/include/arm/v7/section_table.h | 40 ++--- base-hw/src/core/kernel.cc | 8 +- base-hw/src/core/panda_a2/tlb.h | 17 +- base-hw/src/core/pbxa9/tlb.h | 19 ++- base-hw/src/core/rm_session_support.cc | 18 +-- base-hw/src/core/vea9x4/tlb.h | 30 ++-- 9 files changed, 175 insertions(+), 162 deletions(-) diff --git a/base-hw/src/core/imx31/tlb.h b/base-hw/src/core/imx31/tlb.h index 00343ade44..12e8e805c7 100644 --- a/base-hw/src/core/imx31/tlb.h +++ b/base-hw/src/core/imx31/tlb.h @@ -31,6 +31,13 @@ class Tlb : public Arm_v6::Section_table 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 * @@ -42,11 +49,8 @@ class Core_tlb : public Tlb Core_tlb() { - /* map RAM */ - translate_dpm_off(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0, 1); - - /* map MMIO */ - translate_dpm_off(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1, 0); + map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0); + map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1); } }; diff --git a/base-hw/src/core/include/arm/section_table.h b/base-hw/src/core/include/arm/section_table.h index 4fc81e31c0..08a919ccd8 100644 --- a/base-hw/src/core/include/arm/section_table.h +++ b/base-hw/src/core/include/arm/section_table.h @@ -22,6 +22,45 @@ namespace Arm { 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' */ @@ -65,11 +104,10 @@ namespace Arm * \return descriptor value with requested perms and the rest left zero */ template - static typename T::access_t access_permission_bits(bool const w, - bool const x, - bool const k) + static typename T::access_t + access_permission_bits(page_flags_t const flags) { - /* 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_2 Ap_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_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; - 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' */ template - 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::C C; @@ -111,12 +150,14 @@ namespace Arm /* * 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(c) return Tex::bits(6) | C::bits(1) | B::bits(0); - return Tex::bits(4) | C::bits(0) | 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); } /** @@ -253,16 +294,13 @@ namespace Arm /** * Compose descriptor value */ - static access_t create(bool const w, bool const x, - bool const k, bool const g, - bool const d, bool const c, + static access_t create(page_flags_t const flags, addr_t const pa) { - access_t v = access_permission_bits(w, x, k) | - memory_region_attr(d, c) | - Ng::bits(!g) | - S::bits(0) | - Pa_31_12::masked(pa); + access_t v = access_permission_bits(flags) | + memory_region_attr(flags) | + Ng::bits(!Page_flags::G::get(flags)) | + S::bits(0) | Pa_31_12::masked(pa); Descriptor::type(v, Descriptor::SMALL_PAGE); return v; } @@ -335,12 +373,7 @@ namespace Arm * \param pa base of the physical backing store * \param size_log2 log2(Size of the translated region), * must be supported by this table - * \param w see 'Section_table::insert_translation' - * \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' + * \param flags mapping flags * * This method overrides an existing translation in case * 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, unsigned long const size_log2, - bool const w, bool const x, - bool const k, bool const g, - bool const d, bool const c) + page_flags_t const flags) { /* validate virtual address */ unsigned long i; @@ -363,7 +394,7 @@ namespace Arm { /* compose new descriptor value */ 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 */ if (Descriptor::valid(_entries[i])) @@ -614,16 +645,13 @@ namespace Arm /** * Compose descriptor value */ - static access_t create(bool const w, bool const x, - bool const k, bool const g, - bool const d, bool const c, + static access_t create(page_flags_t const flags, addr_t const pa) { - access_t v = access_permission_bits
(w, x, k) | - memory_region_attr
(d, c) | - Domain::bits(DOMAIN) | - S::bits(0) | - Ng::bits(!g) | + access_t v = access_permission_bits
(flags) | + memory_region_attr
(flags) | + Domain::bits(DOMAIN) | S::bits(0) | + Ng::bits(!Page_flags::G::get(flags)) | Pa_31_20::masked(pa); Descriptor::type(v, Descriptor::SECTION); return v; @@ -693,17 +721,7 @@ namespace Arm * region represented by this table * \param pa base of the physical backing store * \param size_log2 size log2 of the translated region - * \param w if one can write trough this translation - * \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 flags mapping flags * \param extra_space If > 0, it must point to a portion of * size-aligned memory space wich may be used * furthermore by the table for the incurring @@ -727,9 +745,7 @@ namespace Arm template unsigned long insert_translation(addr_t const vo, addr_t const pa, unsigned long const size_log2, - bool const w, bool const x, - bool const k, bool const g, - bool const d, bool const c, + page_flags_t const flags, ST * const st, void * const extra_space = 0) { @@ -768,14 +784,14 @@ namespace Arm /* insert translation */ 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; } if (size_log2 == Section::VIRT_SIZE_LOG2) { /* compose section descriptor */ 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 */ if (Descriptor::valid(_entries[i])) @@ -914,25 +930,30 @@ namespace Arm /** * Insert translations for given area, do not permit displacement * - * \param vo virtual offset within this table - * \param s area size - * \param d wether area maps device IO memory - * \param c wether area maps cacheable memory + * \param vo virtual offset within this table + * \param s area size + * \param flags mapping flags */ template - void translate_dpm_off(addr_t vo, size_t s, - bool const d, bool const c, ST * st) + void map_core_area(addr_t vo, size_t s, bool io_mem, ST * st) { + /* initialize parameters */ + page_flags_t const flags = Page_flags::map_core_area(io_mem); unsigned tsl2 = translation_size_l2(vo, s); - size_t ts = 1 << tsl2; - while (1) { - if(st->insert_translation(vo, vo, tsl2, 1,1,0,0,d,c)) { + size_t ts = 1 << tsl2; + + /* 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"); return; } + /* update parameters for next round or exit */ vo += ts; s = ts < s ? s - ts : 0; - if (!s) break; + if (!s) return; tsl2 = translation_size_l2(vo, s); ts = 1 << tsl2; } diff --git a/base-hw/src/core/include/arm/v6/section_table.h b/base-hw/src/core/include/arm/v6/section_table.h index 685e6d21b3..ebbec75faf 100644 --- a/base-hw/src/core/include/arm/v6/section_table.h +++ b/base-hw/src/core/include/arm/v6/section_table.h @@ -53,14 +53,10 @@ namespace Arm_v6 /** * Compose descriptor value */ - static access_t create(bool const w, bool const x, - bool const k, bool const g, - bool const d, bool const c, - addr_t const pa, - Section_table *) + static access_t create(Arm::page_flags_t const flags, + addr_t const pa, Section_table *) { - return Arm::Section_table::Section::create(w, x, k, g, - d, c, pa) | + return Arm::Section_table::Section::create(flags, pa) | P::bits(0); } }; @@ -70,33 +66,25 @@ namespace Arm_v6 * * For details see 'Arm::Section_table::insert_translation' */ - unsigned long insert_translation(addr_t const vo, addr_t const pa, - unsigned long const size_log2, - bool const w, bool const x, - bool const k, bool const g, - bool const d, bool const c, - void * const extra_space = 0) - { + unsigned long + insert_translation(addr_t const vo, addr_t const pa, + unsigned long const size_log2, + Arm::page_flags_t const flags, + void * const extra_space = 0) { return Arm::Section_table:: - insert_translation(vo, pa, size_log2, w, - x, k, g, d, c, this, - extra_space); - } + insert_translation(vo, pa, size_log2, flags, + this, extra_space); } /** * Insert translations for given area, do not permit displacement * - * \param vo virtual offset within this table - * \param s area size - * \param d wether area maps device IO memory - * \param c wether area maps cacheable memory + * \param vo virtual offset within this table + * \param s area size + * \param io_mem wether the area maps MMIO */ - void translate_dpm_off(addr_t vo, size_t s, - bool const d, bool const c) - { - Arm::Section_table:: - translate_dpm_off(vo, s, d, c, this); - } + void map_core_area(addr_t vo, size_t s, bool const io_mem) { + Arm::Section_table::map_core_area(vo, s, io_mem, + this); } }; } diff --git a/base-hw/src/core/include/arm/v7/section_table.h b/base-hw/src/core/include/arm/v7/section_table.h index 1e08046532..cafd7b462a 100644 --- a/base-hw/src/core/include/arm/v7/section_table.h +++ b/base-hw/src/core/include/arm/v7/section_table.h @@ -57,13 +57,11 @@ namespace Arm_v7 /** * Compose descriptor value */ - static access_t create(bool const w, bool const x, - bool const k, bool const g, - bool const d, bool const c, + static access_t create(Arm::page_flags_t const flags, addr_t const pa, 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()); } }; @@ -85,33 +83,25 @@ namespace Arm_v7 * * For details see 'Arm::Section_table::insert_translation' */ - unsigned long insert_translation(addr_t const vo, addr_t const pa, - unsigned long const size_log2, - bool const w, bool const x, - bool const k, bool const g, - bool const d, bool const c, - void * const extra_space = 0) - { + unsigned long + insert_translation(addr_t const vo, addr_t const pa, + unsigned long const size_log2, + Arm::page_flags_t const flags, + void * const extra_space = 0) { return Arm::Section_table:: - insert_translation(vo, pa, size_log2, w, - x, k, g, d, c, this, - extra_space); - } + insert_translation(vo, pa, size_log2, flags, + this, extra_space); } /** * Insert translations for given area, do not permit displacement * - * \param vo virtual offset within this table - * \param s area size - * \param d wether area maps device IO memory - * \param c wether area maps cacheable memory + * \param vo virtual offset within this table + * \param s area size + * \param io_mem wether the area maps MMIO */ - void translate_dpm_off(addr_t vo, size_t s, - bool const d, bool const c) - { - Arm::Section_table:: - translate_dpm_off(vo, s, d, c, this); - } + void map_core_area(addr_t vo, size_t s, bool const io_mem) { + Arm::Section_table::map_core_area(vo, s, io_mem, + this); } /*************** ** Accessors ** diff --git a/base-hw/src/core/kernel.cc b/base-hw/src/core/kernel.cc index 710132dda0..faf2020836 100644 --- a/base-hw/src/core/kernel.cc +++ b/base-hw/src/core/kernel.cc @@ -801,12 +801,11 @@ namespace Kernel Pd(Tlb * const t) : _tlb(t) { /* 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 = tlb()->insert_translation(mtc()->VIRT_BASE, mtc()->phys_base(), - mtc()->SIZE_LOG2, - W, X, K, G, D, C); + mtc()->SIZE_LOG2, flags); /* extra space needed to translate mode transition region */ if (slog2) @@ -824,8 +823,7 @@ namespace Kernel /* translate mode transition region globally */ tlb()->insert_translation(mtc()->VIRT_BASE, mtc()->phys_base(), - mtc()->SIZE_LOG2, - W, X, K, G, D, C, + mtc()->SIZE_LOG2, flags, (void *)aligned_es); } } diff --git a/base-hw/src/core/panda_a2/tlb.h b/base-hw/src/core/panda_a2/tlb.h index a4a2b6a204..56f30adad2 100644 --- a/base-hw/src/core/panda_a2/tlb.h +++ b/base-hw/src/core/panda_a2/tlb.h @@ -33,6 +33,13 @@ class Tlb : public Arm_v7::Section_table 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 * @@ -45,13 +52,9 @@ class Core_tlb : public Tlb Core_tlb() { using namespace Genode; - - /* map RAM */ - translate_dpm_off(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0, 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); + map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0); + map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1); + map_core_area(Board::MMIO_1_BASE, Board::MMIO_1_SIZE, 1); } }; diff --git a/base-hw/src/core/pbxa9/tlb.h b/base-hw/src/core/pbxa9/tlb.h index 674f84b83e..ffd92838ce 100644 --- a/base-hw/src/core/pbxa9/tlb.h +++ b/base-hw/src/core/pbxa9/tlb.h @@ -33,6 +33,13 @@ class Tlb : public Arm_v7::Section_table 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 * @@ -45,14 +52,10 @@ class Core_tlb : public Tlb Core_tlb() { using namespace Genode; - - /* map RAM */ - translate_dpm_off(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0, 1); - translate_dpm_off(Board::RAM_1_BASE, Board::RAM_1_SIZE, 0, 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); + map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0); + map_core_area(Board::RAM_1_BASE, Board::RAM_1_SIZE, 0); + map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1); + map_core_area(Board::MMIO_1_BASE, Board::MMIO_1_SIZE, 1); } }; diff --git a/base-hw/src/core/rm_session_support.cc b/base-hw/src/core/rm_session_support.cc index ca46b88994..51733c9250 100644 --- a/base-hw/src/core/rm_session_support.cc +++ b/base-hw/src/core/rm_session_support.cc @@ -57,16 +57,17 @@ void Ipc_pager::resolve_and_wait_for_fault() /* valid mapping? */ assert(_mapping.valid()); - /* do we need extra space to resolve pagefault? */ + /* prepare mapping */ Tlb * const tlb = _pagefault.tlb; - enum { X = 1, K = 0, G = 0 }; - bool c = !_mapping.write_combined && !_mapping.io_mem; - bool d = _mapping.io_mem; + page_flags_t const flags = + Page_flags::resolve_and_wait_for_fault(_mapping.writable, + _mapping.write_combined, + _mapping.io_mem); /* insert mapping into TLB */ - unsigned sl2 = tlb->insert_translation(_mapping.virt_address, - _mapping.phys_address, _mapping.size_log2, - _mapping.writable, X, K, G, d, c); + unsigned sl2; + sl2 = tlb->insert_translation(_mapping.virt_address, _mapping.phys_address, + _mapping.size_log2, flags); if (sl2) { /* 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 */ sl2 = tlb->insert_translation(_mapping.virt_address, _mapping.phys_address, - _mapping.size_log2, - _mapping.writable, X, K, G, d, c, space); + _mapping.size_log2, flags, space); assert(!sl2); } /* try to wake up faulter */ diff --git a/base-hw/src/core/vea9x4/tlb.h b/base-hw/src/core/vea9x4/tlb.h index 04315506d6..0244839ea1 100644 --- a/base-hw/src/core/vea9x4/tlb.h +++ b/base-hw/src/core/vea9x4/tlb.h @@ -33,28 +33,34 @@ class Tlb : public Arm_v7::Section_table 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 - * - * Must ensure that core never gets a pagefault. */ class Core_tlb : public Tlb { public: + /** + * Constructor + * + * Must ensure that core never gets a pagefault. + */ Core_tlb() { using namespace Genode; - - /* map RAM */ - translate_dpm_off(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0, 1); - translate_dpm_off(Board::RAM_1_BASE, Board::RAM_1_SIZE, 0, 1); - translate_dpm_off(Board::RAM_2_BASE, Board::RAM_2_SIZE, 0, 1); - translate_dpm_off(Board::RAM_3_BASE, Board::RAM_3_SIZE, 0, 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); + map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0); + map_core_area(Board::RAM_1_BASE, Board::RAM_1_SIZE, 0); + map_core_area(Board::RAM_2_BASE, Board::RAM_2_SIZE, 0); + map_core_area(Board::RAM_3_BASE, Board::RAM_3_SIZE, 0); + map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1); + map_core_area(Board::MMIO_1_BASE, Board::MMIO_1_SIZE, 1); } };