hw & arm: exceptions to asserts in transl. table

ref #474
This commit is contained in:
Martin Stein 2014-08-05 21:49:26 +02:00 committed by Norman Feske
parent e686aee5f9
commit 03cd76821c

View File

@ -19,7 +19,9 @@
#include <util/register.h> #include <util/register.h>
#include <base/printf.h> #include <base/printf.h>
/* base-hw includes */ /* core includes */
#include <util.h>
#include <assert.h>
#include <page_flags.h> #include <page_flags.h>
#include <page_slab.h> #include <page_slab.h>
#include <cpu.h> #include <cpu.h>
@ -41,24 +43,8 @@ namespace Genode
class Genode::Translation_table class Genode::Translation_table
{ {
public:
/***************************
** Exception definitions **
***************************/
class Double_insertion {};
class Misaligned {};
class Invalid_range {};
private: private:
/**
* Check if 'p' is aligned to 1 << 'alignm_log2'
*/
static inline bool aligned(addr_t const a, size_t const alignm_log2) {
return a == ((a >> alignm_log2) << alignm_log2); }
/** /**
* Return permission configuration according to given mapping flags * Return permission configuration according to given mapping flags
* *
@ -224,10 +210,7 @@ class Genode::Translation_table
*/ */
Page_table() Page_table()
{ {
if (!aligned((addr_t)this, ALIGNM_LOG2)) assert(aligned(this, ALIGNM_LOG2));
throw Misaligned();
/* start with an empty table */
memset(&_entries, 0, sizeof(_entries)); memset(&_entries, 0, sizeof(_entries));
} }
@ -249,10 +232,6 @@ class Genode::Translation_table
* \param pa base of the physical backing store * \param pa base of the physical backing store
* \param size size of the translated region * \param size size of the translated region
* \param flags mapping flags * \param flags mapping flags
*
* This method overrides an existing translation in case
* that it spans the the same virtual range otherwise it
* throws a Double_insertion.
*/ */
void insert_translation(addr_t vo, void insert_translation(addr_t vo,
addr_t pa, addr_t pa,
@ -261,17 +240,23 @@ class Genode::Translation_table
{ {
constexpr size_t sz = Descriptor::VIRT_SIZE; constexpr size_t sz = Descriptor::VIRT_SIZE;
for (unsigned i; (size > 0) && _index_by_vo (i, vo); for (unsigned i; (size > 0) && _index_by_vo(i, vo);
size = (size < sz) ? 0 : size - sz, vo += sz, pa += sz) { size = (size < sz) ? 0 : size - sz,
vo += sz, pa += sz)
if (Descriptor::valid(_entries[i]) && {
_entries[i] != Small_page::create(flags, pa))
throw Double_insertion();
/* compose new descriptor value */ /* compose new descriptor value */
_entries[i] = Small_page::create(flags, pa); Small_page::access_t const e =
Small_page::create(flags, pa);
/* some processors need to act on changed translations */ /* check if it is a good idea to override the entry */
assert(!Descriptor::valid(_entries[i]) ||
_entries[i] == e);
/* override entry */
_entries[i] = e;
/* some CPUs need to act on changed translations */
Cpu::translation_added((addr_t)&_entries[i], Cpu::translation_added((addr_t)&_entries[i],
sizeof(Descriptor::access_t)); sizeof(Descriptor::access_t));
} }
@ -528,10 +513,7 @@ class Genode::Translation_table
break; break;
} }
default: default: assert(0);
{
throw Double_insertion();
}
}; };
/* insert translation */ /* insert translation */
@ -551,10 +533,7 @@ class Genode::Translation_table
*/ */
Translation_table() Translation_table()
{ {
if (!aligned((addr_t)this, ALIGNM_LOG2)) assert(aligned(this, ALIGNM_LOG2));
throw Misaligned();
/* start with an empty table */
memset(&_entries, 0, sizeof(_entries)); memset(&_entries, 0, sizeof(_entries));
} }
@ -584,10 +563,9 @@ class Genode::Translation_table
Page_flags const & flags, Page_flags const & flags,
Page_slab * slab) Page_slab * slab)
{ {
/* sanity check */ /* check sanity */
if ((vo & Page_table::Descriptor::VIRT_OFFSET_MASK) assert(!(vo & Page_table::Descriptor::VIRT_OFFSET_MASK) &&
|| size < Page_table::Descriptor::VIRT_SIZE) size >= Page_table::Descriptor::VIRT_SIZE);
throw Invalid_range();
for (unsigned i; (size > 0) && _index_by_vo (i, vo);) { for (unsigned i; (size > 0) && _index_by_vo (i, vo);) {
@ -599,12 +577,17 @@ class Genode::Translation_table
case Descriptor::SECTION: case Descriptor::SECTION:
{ {
if (Descriptor::valid(_entries[i]) && /* compose new entry */
_entries[i] != Section::create(flags, pa)) Section::access_t const e = Section::create(flags, pa);
throw Double_insertion();
_entries[i] = Section::create(flags, pa);
/* some processors need to act on changed translations */ /* check if it is a good idea to override the entry */
assert(!Descriptor::valid(_entries[i]) ||
_entries[i] == e);
/* override entry */
_entries[i] = e;
/* some CPUs need to act on changed translations */
Cpu::translation_added((addr_t)&_entries[i], Cpu::translation_added((addr_t)&_entries[i],
sizeof(Descriptor::access_t)); sizeof(Descriptor::access_t));
break; break;
@ -635,7 +618,8 @@ class Genode::Translation_table
*/ */
void remove_translation(addr_t vo, size_t size, Page_slab * slab) void remove_translation(addr_t vo, size_t size, Page_slab * slab)
{ {
if (vo > (vo + size)) throw Invalid_range(); /* check sanity */
assert(vo <= (vo + size));
for (unsigned i; (size > 0) && _index_by_vo(i, vo);) { for (unsigned i; (size > 0) && _index_by_vo(i, vo);) {