hw: simplify Page_flags (fix #711)
Instead of using a special bitfield use a compound of boolean values for the generic page attributes. To reduce copy overhead, change the corresponding functions, where Page_flags are used as arguments, to use references.
This commit is contained in:
parent
47179201a5
commit
2ed22595ff
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
struct Page_flags : Arm::Page_flags { };
|
|
||||||
|
|
||||||
class Tlb : public Arm_v7::Section_table { };
|
class Tlb : public Arm_v7::Section_table { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
struct Page_flags : Arm::Page_flags { };
|
|
||||||
|
|
||||||
class Tlb : public Arm_v6::Section_table { };
|
class Tlb : public Arm_v6::Section_table { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
struct Page_flags : Arm::Page_flags { };
|
|
||||||
|
|
||||||
class Tlb : public Arm_v7::Section_table { };
|
class Tlb : public Arm_v7::Section_table { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,8 +23,6 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
struct Page_flags : Arm::Page_flags { };
|
|
||||||
|
|
||||||
class Tlb : public Arm_v7::Section_table { };
|
class Tlb : public Arm_v7::Section_table { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -119,10 +119,10 @@ class Kernel::Mode_transition_control
|
||||||
*/
|
*/
|
||||||
size_t map(Tlb * tlb, addr_t ram = 0)
|
size_t map(Tlb * tlb, addr_t ram = 0)
|
||||||
{
|
{
|
||||||
Page_flags::access_t const flags = Page_flags::mode_transition();
|
|
||||||
addr_t const phys_base = (addr_t)&_mt_begin;
|
addr_t const phys_base = (addr_t)&_mt_begin;
|
||||||
return tlb->insert_translation(VIRT_BASE, phys_base, SIZE_LOG2,
|
return tlb->insert_translation(VIRT_BASE, phys_base, SIZE_LOG2,
|
||||||
flags, (void *)ram);
|
Page_flags::mode_transition(),
|
||||||
|
(void *)ram);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
struct Page_flags : Arm::Page_flags { };
|
|
||||||
|
|
||||||
class Tlb : public Arm_v7::Section_table { };
|
class Tlb : public Arm_v7::Section_table { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
struct Page_flags : Arm::Page_flags { };
|
|
||||||
|
|
||||||
class Tlb : public Arm_v7::Section_table { };
|
class Tlb : public Arm_v7::Section_table { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,7 +56,7 @@ int Pager_activation_base::apply_mapping()
|
||||||
{
|
{
|
||||||
/* prepare mapping */
|
/* prepare mapping */
|
||||||
Tlb * const tlb = (Tlb *)_fault.tlb;
|
Tlb * const tlb = (Tlb *)_fault.tlb;
|
||||||
Page_flags::access_t const flags =
|
Page_flags const flags =
|
||||||
Page_flags::apply_mapping(_mapping.writable,
|
Page_flags::apply_mapping(_mapping.writable,
|
||||||
_mapping.write_combined,
|
_mapping.write_combined,
|
||||||
_mapping.io_mem);
|
_mapping.io_mem);
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
struct Page_flags : Arm::Page_flags { };
|
|
||||||
|
|
||||||
class Tlb : public Arm_v6::Section_table { };
|
class Tlb : public Arm_v6::Section_table { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,48 +20,12 @@
|
||||||
|
|
||||||
/* base-hw includes */
|
/* base-hw includes */
|
||||||
#include <placement_new.h>
|
#include <placement_new.h>
|
||||||
|
#include <tlb/page_flags.h>
|
||||||
|
|
||||||
namespace Arm
|
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
|
|
||||||
apply_mapping(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); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if 'p' is aligned to 1 << 'alignm_log2'
|
* Check if 'p' is aligned to 1 << 'alignm_log2'
|
||||||
*/
|
*/
|
||||||
|
@ -104,7 +68,7 @@ namespace Arm
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static typename T::access_t
|
static typename T::access_t
|
||||||
access_permission_bits(Page_flags::access_t const flags)
|
access_permission_bits(Page_flags const &flags)
|
||||||
{
|
{
|
||||||
/* lookup table for AP bitfield values according to 'w' and 'k' flag */
|
/* 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;
|
||||||
|
@ -131,8 +95,8 @@ namespace Arm
|
||||||
};
|
};
|
||||||
/* combine XN and AP bitfield values according to the flags */
|
/* combine XN and AP bitfield values according to the flags */
|
||||||
typedef typename T::Xn Xn;
|
typedef typename T::Xn Xn;
|
||||||
return Xn::bits(!Page_flags::X::get(flags)) |
|
return Xn::bits(!flags.executable) |
|
||||||
ap_bits[Page_flags::W::get(flags)][Page_flags::K::get(flags)];
|
ap_bits[flags.writeable][flags.privileged];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,7 +104,7 @@ namespace Arm
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static typename T::access_t
|
static typename T::access_t
|
||||||
memory_region_attr(Page_flags::access_t const flags);
|
memory_region_attr(Page_flags const &flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Second level translation table
|
* Second level translation table
|
||||||
|
@ -276,12 +240,12 @@ namespace Arm
|
||||||
/**
|
/**
|
||||||
* Compose descriptor value
|
* Compose descriptor value
|
||||||
*/
|
*/
|
||||||
static access_t create(Page_flags::access_t const flags,
|
static access_t create(Page_flags const &flags,
|
||||||
addr_t const pa)
|
addr_t const pa)
|
||||||
{
|
{
|
||||||
access_t v = access_permission_bits<Small_page>(flags) |
|
access_t v = access_permission_bits<Small_page>(flags) |
|
||||||
memory_region_attr<Small_page>(flags) |
|
memory_region_attr<Small_page>(flags) |
|
||||||
Ng::bits(!Page_flags::G::get(flags)) |
|
Ng::bits(!flags.global) |
|
||||||
S::bits(0) | Pa_31_12::masked(pa);
|
S::bits(0) | Pa_31_12::masked(pa);
|
||||||
Descriptor::type(v, Descriptor::SMALL_PAGE);
|
Descriptor::type(v, Descriptor::SMALL_PAGE);
|
||||||
return v;
|
return v;
|
||||||
|
@ -358,7 +322,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,
|
||||||
size_t const size_log2,
|
size_t const size_log2,
|
||||||
Page_flags::access_t const flags)
|
Page_flags const &flags)
|
||||||
{
|
{
|
||||||
/* validate virtual address */
|
/* validate virtual address */
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -618,13 +582,13 @@ namespace Arm
|
||||||
/**
|
/**
|
||||||
* Compose descriptor value
|
* Compose descriptor value
|
||||||
*/
|
*/
|
||||||
static access_t create(Page_flags::access_t const flags,
|
static access_t create(Page_flags const &flags,
|
||||||
addr_t const pa)
|
addr_t const pa)
|
||||||
{
|
{
|
||||||
access_t v = access_permission_bits<Section>(flags) |
|
access_t v = access_permission_bits<Section>(flags) |
|
||||||
memory_region_attr<Section>(flags) |
|
memory_region_attr<Section>(flags) |
|
||||||
Domain::bits(DOMAIN) | S::bits(0) |
|
Domain::bits(DOMAIN) | S::bits(0) |
|
||||||
Ng::bits(!Page_flags::G::get(flags)) |
|
Ng::bits(!flags.global) |
|
||||||
Pa_31_20::masked(pa);
|
Pa_31_20::masked(pa);
|
||||||
Descriptor::type(v, Descriptor::SECTION);
|
Descriptor::type(v, Descriptor::SECTION);
|
||||||
return v;
|
return v;
|
||||||
|
@ -723,7 +687,7 @@ namespace Arm
|
||||||
template <typename ST>
|
template <typename ST>
|
||||||
size_t insert_translation(addr_t const vo, addr_t const pa,
|
size_t insert_translation(addr_t const vo, addr_t const pa,
|
||||||
size_t const size_log2,
|
size_t const size_log2,
|
||||||
Page_flags::access_t const flags,
|
Page_flags const &flags,
|
||||||
ST * const st,
|
ST * const st,
|
||||||
void * const extra_space = 0)
|
void * const extra_space = 0)
|
||||||
{
|
{
|
||||||
|
@ -908,8 +872,7 @@ namespace Arm
|
||||||
void map_core_area(addr_t vo, size_t s, bool io_mem, ST * st)
|
void map_core_area(addr_t vo, size_t s, bool io_mem, ST * st)
|
||||||
{
|
{
|
||||||
/* initialize parameters */
|
/* initialize parameters */
|
||||||
Page_flags::access_t const flags =
|
Page_flags const flags = Page_flags::map_core_area(io_mem);
|
||||||
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;
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace Arm_v6
|
||||||
/**
|
/**
|
||||||
* Compose descriptor value
|
* Compose descriptor value
|
||||||
*/
|
*/
|
||||||
static access_t create(Arm::Page_flags::access_t const flags,
|
static access_t create(Page_flags const &flags,
|
||||||
addr_t const pa, Section_table *)
|
addr_t const pa, Section_table *)
|
||||||
{
|
{
|
||||||
return Arm::Section_table::Section::create(flags, pa) |
|
return Arm::Section_table::Section::create(flags, pa) |
|
||||||
|
@ -69,7 +69,7 @@ namespace Arm_v6
|
||||||
size_t
|
size_t
|
||||||
insert_translation(addr_t const vo, addr_t const pa,
|
insert_translation(addr_t const vo, addr_t const pa,
|
||||||
size_t const size_log2,
|
size_t const size_log2,
|
||||||
Arm::Page_flags::access_t const flags,
|
Page_flags const &flags,
|
||||||
void * const extra_space = 0) {
|
void * const extra_space = 0) {
|
||||||
return Arm::Section_table::
|
return Arm::Section_table::
|
||||||
insert_translation<Section_table>(vo, pa, size_log2, flags,
|
insert_translation<Section_table>(vo, pa, size_log2, flags,
|
||||||
|
@ -91,7 +91,7 @@ namespace Arm_v6
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static typename T::access_t
|
static typename T::access_t
|
||||||
Arm::memory_region_attr(Arm::Page_flags::access_t const flags)
|
Arm::memory_region_attr(Page_flags const &flags)
|
||||||
{
|
{
|
||||||
typedef typename T::Tex Tex;
|
typedef typename T::Tex Tex;
|
||||||
typedef typename T::C C;
|
typedef typename T::C C;
|
||||||
|
@ -100,10 +100,10 @@ Arm::memory_region_attr(Arm::Page_flags::access_t const flags)
|
||||||
/*
|
/*
|
||||||
* FIXME: upgrade to write-back & write-allocate when !d & c
|
* FIXME: upgrade to write-back & write-allocate when !d & c
|
||||||
*/
|
*/
|
||||||
if(Arm::Page_flags::D::get(flags))
|
if(flags.device)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(Arm::Page_flags::C::get(flags))
|
if(flags.cacheable)
|
||||||
return Tex::bits(5) | C::bits(0) | B::bits(1);
|
return Tex::bits(5) | C::bits(0) | B::bits(1);
|
||||||
|
|
||||||
return Tex::bits(6) | C::bits(1) | B::bits(0);
|
return Tex::bits(6) | C::bits(1) | B::bits(0);
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Arm_v7
|
||||||
/**
|
/**
|
||||||
* Compose descriptor value
|
* Compose descriptor value
|
||||||
*/
|
*/
|
||||||
static access_t create(Arm::Page_flags::access_t const flags,
|
static access_t create(Page_flags const &flags,
|
||||||
addr_t const pa,
|
addr_t const pa,
|
||||||
Section_table * const st)
|
Section_table * const st)
|
||||||
{
|
{
|
||||||
|
@ -86,7 +86,7 @@ namespace Arm_v7
|
||||||
size_t
|
size_t
|
||||||
insert_translation(addr_t const vo, addr_t const pa,
|
insert_translation(addr_t const vo, addr_t const pa,
|
||||||
size_t const size_log2,
|
size_t const size_log2,
|
||||||
Arm::Page_flags::access_t const flags,
|
Page_flags const &flags,
|
||||||
void * const extra_space = 0) {
|
void * const extra_space = 0) {
|
||||||
return Arm::Section_table::
|
return Arm::Section_table::
|
||||||
insert_translation<Section_table>(vo, pa, size_log2, flags,
|
insert_translation<Section_table>(vo, pa, size_log2, flags,
|
||||||
|
@ -114,7 +114,7 @@ namespace Arm_v7
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static typename T::access_t
|
static typename T::access_t
|
||||||
Arm::memory_region_attr(Arm::Page_flags::access_t const flags)
|
Arm::memory_region_attr(Page_flags const &flags)
|
||||||
{
|
{
|
||||||
typedef typename T::Tex Tex;
|
typedef typename T::Tex Tex;
|
||||||
typedef typename T::C C;
|
typedef typename T::C C;
|
||||||
|
@ -123,10 +123,10 @@ Arm::memory_region_attr(Arm::Page_flags::access_t const flags)
|
||||||
/*
|
/*
|
||||||
* FIXME: upgrade to write-back & write-allocate when !d & c
|
* FIXME: upgrade to write-back & write-allocate when !d & c
|
||||||
*/
|
*/
|
||||||
if(Arm::Page_flags::D::get(flags))
|
if(flags.device)
|
||||||
return Tex::bits(2) | C::bits(0) | B::bits(0);
|
return Tex::bits(2) | C::bits(0) | B::bits(0);
|
||||||
|
|
||||||
if(Arm::Page_flags::C::get(flags))
|
if(flags.cacheable)
|
||||||
return Tex::bits(5) | C::bits(0) | B::bits(1);
|
return Tex::bits(5) | C::bits(0) | B::bits(1);
|
||||||
|
|
||||||
return Tex::bits(6) | C::bits(1) | B::bits(0);
|
return Tex::bits(6) | C::bits(1) | B::bits(0);
|
||||||
|
|
55
base-hw/src/core/tlb/page_flags.h
Normal file
55
base-hw/src/core/tlb/page_flags.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* \brief Generic page flags
|
||||||
|
* \author Stefan Kalkowski
|
||||||
|
* \date 2014-02-24
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TLB__PAGE_FLAGS_H_
|
||||||
|
#define _TLB__PAGE_FLAGS_H_
|
||||||
|
|
||||||
|
namespace Genode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Map app-specific mem attributes to a TLB-specific POD
|
||||||
|
*/
|
||||||
|
struct Page_flags
|
||||||
|
{
|
||||||
|
bool writeable;
|
||||||
|
bool executable;
|
||||||
|
bool privileged;
|
||||||
|
bool global;
|
||||||
|
bool device;
|
||||||
|
bool cacheable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create flag POD for Genode pagers
|
||||||
|
*/
|
||||||
|
static const Page_flags
|
||||||
|
apply_mapping(bool const writeable,
|
||||||
|
bool const write_combined,
|
||||||
|
bool const io_mem) {
|
||||||
|
return Page_flags { writeable, true, false, false,
|
||||||
|
io_mem, !write_combined && !io_mem }; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create flag POD for kernel when it creates the core space
|
||||||
|
*/
|
||||||
|
static const Page_flags map_core_area(bool const io_mem) {
|
||||||
|
return Page_flags { true, true, false, false, io_mem, !io_mem }; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create flag POD for the mode transition region
|
||||||
|
*/
|
||||||
|
static const Page_flags mode_transition() {
|
||||||
|
return Page_flags { true, true, true, true, false, true }; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _TLB__PAGE_FLAGS_H_ */
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
struct Page_flags : Arm::Page_flags { };
|
|
||||||
|
|
||||||
class Tlb : public Arm_v7::Section_table { };
|
class Tlb : public Arm_v7::Section_table { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,8 +23,6 @@
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
{
|
{
|
||||||
struct Page_flags : Arm::Page_flags { };
|
|
||||||
|
|
||||||
class Tlb : public Arm_v7::Section_table { };
|
class Tlb : public Arm_v7::Section_table { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user