mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 02:01:38 +00:00
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
|
||||
{
|
||||
struct Page_flags : Arm::Page_flags { };
|
||||
|
||||
class Tlb : public Arm_v7::Section_table { };
|
||||
|
||||
/**
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
struct Page_flags : Arm::Page_flags { };
|
||||
|
||||
class Tlb : public Arm_v6::Section_table { };
|
||||
|
||||
/**
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
struct Page_flags : Arm::Page_flags { };
|
||||
|
||||
class Tlb : public Arm_v7::Section_table { };
|
||||
|
||||
/**
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
struct Page_flags : Arm::Page_flags { };
|
||||
|
||||
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)
|
||||
{
|
||||
Page_flags::access_t const flags = Page_flags::mode_transition();
|
||||
addr_t const phys_base = (addr_t)&_mt_begin;
|
||||
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
|
||||
{
|
||||
struct Page_flags : Arm::Page_flags { };
|
||||
|
||||
class Tlb : public Arm_v7::Section_table { };
|
||||
|
||||
/**
|
||||
|
@ -20,8 +20,6 @@
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
struct Page_flags : Arm::Page_flags { };
|
||||
|
||||
class Tlb : public Arm_v7::Section_table { };
|
||||
|
||||
/**
|
||||
|
@ -56,7 +56,7 @@ int Pager_activation_base::apply_mapping()
|
||||
{
|
||||
/* prepare mapping */
|
||||
Tlb * const tlb = (Tlb *)_fault.tlb;
|
||||
Page_flags::access_t const flags =
|
||||
Page_flags const flags =
|
||||
Page_flags::apply_mapping(_mapping.writable,
|
||||
_mapping.write_combined,
|
||||
_mapping.io_mem);
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
struct Page_flags : Arm::Page_flags { };
|
||||
|
||||
class Tlb : public Arm_v6::Section_table { };
|
||||
|
||||
/**
|
||||
|
@ -20,48 +20,12 @@
|
||||
|
||||
/* base-hw includes */
|
||||
#include <placement_new.h>
|
||||
#include <tlb/page_flags.h>
|
||||
|
||||
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
|
||||
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'
|
||||
*/
|
||||
@ -104,7 +68,7 @@ namespace Arm
|
||||
*/
|
||||
template <typename 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 */
|
||||
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 */
|
||||
typedef typename T::Xn Xn;
|
||||
return Xn::bits(!Page_flags::X::get(flags)) |
|
||||
ap_bits[Page_flags::W::get(flags)][Page_flags::K::get(flags)];
|
||||
return Xn::bits(!flags.executable) |
|
||||
ap_bits[flags.writeable][flags.privileged];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,7 +104,7 @@ namespace Arm
|
||||
*/
|
||||
template <typename 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
|
||||
@ -276,12 +240,12 @@ namespace Arm
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
access_t v = access_permission_bits<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);
|
||||
Descriptor::type(v, Descriptor::SMALL_PAGE);
|
||||
return v;
|
||||
@ -358,7 +322,7 @@ namespace Arm
|
||||
*/
|
||||
void insert_translation(addr_t const vo, addr_t const pa,
|
||||
size_t const size_log2,
|
||||
Page_flags::access_t const flags)
|
||||
Page_flags const &flags)
|
||||
{
|
||||
/* validate virtual address */
|
||||
unsigned i;
|
||||
@ -618,13 +582,13 @@ namespace Arm
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
access_t v = access_permission_bits<Section>(flags) |
|
||||
memory_region_attr<Section>(flags) |
|
||||
Domain::bits(DOMAIN) | S::bits(0) |
|
||||
Ng::bits(!Page_flags::G::get(flags)) |
|
||||
Ng::bits(!flags.global) |
|
||||
Pa_31_20::masked(pa);
|
||||
Descriptor::type(v, Descriptor::SECTION);
|
||||
return v;
|
||||
@ -723,7 +687,7 @@ namespace Arm
|
||||
template <typename ST>
|
||||
size_t insert_translation(addr_t const vo, addr_t const pa,
|
||||
size_t const size_log2,
|
||||
Page_flags::access_t const flags,
|
||||
Page_flags const &flags,
|
||||
ST * const st,
|
||||
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)
|
||||
{
|
||||
/* initialize parameters */
|
||||
Page_flags::access_t const flags =
|
||||
Page_flags::map_core_area(io_mem);
|
||||
Page_flags const flags = Page_flags::map_core_area(io_mem);
|
||||
unsigned tsl2 = translation_size_l2(vo, s);
|
||||
size_t ts = 1 << tsl2;
|
||||
|
||||
|
@ -53,7 +53,7 @@ namespace Arm_v6
|
||||
/**
|
||||
* 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 *)
|
||||
{
|
||||
return Arm::Section_table::Section::create(flags, pa) |
|
||||
@ -69,7 +69,7 @@ namespace Arm_v6
|
||||
size_t
|
||||
insert_translation(addr_t const vo, addr_t const pa,
|
||||
size_t const size_log2,
|
||||
Arm::Page_flags::access_t const flags,
|
||||
Page_flags const &flags,
|
||||
void * const extra_space = 0) {
|
||||
return Arm::Section_table::
|
||||
insert_translation<Section_table>(vo, pa, size_log2, flags,
|
||||
@ -91,7 +91,7 @@ namespace Arm_v6
|
||||
|
||||
template <typename 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::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
|
||||
*/
|
||||
if(Arm::Page_flags::D::get(flags))
|
||||
if(flags.device)
|
||||
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(6) | C::bits(1) | B::bits(0);
|
||||
|
@ -57,7 +57,7 @@ namespace Arm_v7
|
||||
/**
|
||||
* 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 * const st)
|
||||
{
|
||||
@ -86,7 +86,7 @@ namespace Arm_v7
|
||||
size_t
|
||||
insert_translation(addr_t const vo, addr_t const pa,
|
||||
size_t const size_log2,
|
||||
Arm::Page_flags::access_t const flags,
|
||||
Page_flags const &flags,
|
||||
void * const extra_space = 0) {
|
||||
return Arm::Section_table::
|
||||
insert_translation<Section_table>(vo, pa, size_log2, flags,
|
||||
@ -114,7 +114,7 @@ namespace Arm_v7
|
||||
|
||||
template <typename 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::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
|
||||
*/
|
||||
if(Arm::Page_flags::D::get(flags))
|
||||
if(flags.device)
|
||||
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(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
|
||||
{
|
||||
struct Page_flags : Arm::Page_flags { };
|
||||
|
||||
class Tlb : public Arm_v7::Section_table { };
|
||||
|
||||
/**
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
struct Page_flags : Arm::Page_flags { };
|
||||
|
||||
class Tlb : public Arm_v7::Section_table { };
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user