mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-31 14:40:54 +00:00
Extract more generic parts from 'Genode::Mmio'
To accommodate CPU registers, which have a structured layout but don't depend on a region base address, this patch introduces the generic 'Genode::Register' and 'Genode::Subreg' to 'register.h'. 'Mmio::Register' and 'Mmio::Subreg' inherit from them.
This commit is contained in:
parent
1f75ebe9e5
commit
9329b91aca
@ -7,7 +7,7 @@
|
|||||||
#ifndef _BASE__INCLUDE__UTIL__MMIO_H_
|
#ifndef _BASE__INCLUDE__UTIL__MMIO_H_
|
||||||
#define _BASE__INCLUDE__UTIL__MMIO_H_
|
#define _BASE__INCLUDE__UTIL__MMIO_H_
|
||||||
|
|
||||||
#include <base/stdint.h>
|
#include <util/register.h>
|
||||||
|
|
||||||
|
|
||||||
namespace Genode
|
namespace Genode
|
||||||
@ -45,40 +45,24 @@ namespace Genode
|
|||||||
* A POD-like region at offset 'MMIO_OFFSET' within a MMIO region
|
* A POD-like region at offset 'MMIO_OFFSET' within a MMIO region
|
||||||
*/
|
*/
|
||||||
template <off_t MMIO_OFFSET, typename STORAGE_T>
|
template <off_t MMIO_OFFSET, typename STORAGE_T>
|
||||||
struct Register
|
struct Register : public Genode::Register<STORAGE_T>
|
||||||
{
|
{
|
||||||
typedef STORAGE_T storage_t;
|
|
||||||
enum { OFFSET = MMIO_OFFSET };
|
enum { OFFSET = MMIO_OFFSET };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bitregion within a register
|
* A bitregion within a register
|
||||||
*/
|
*/
|
||||||
template <unsigned long BIT_SHIFT, unsigned long BIT_SIZE>
|
template <unsigned long BIT_SHIFT, unsigned long BIT_SIZE>
|
||||||
struct Subreg
|
struct Subreg : public Genode::Register<STORAGE_T>::template Subreg<BIT_SHIFT, BIT_SIZE>
|
||||||
{
|
{
|
||||||
enum {
|
|
||||||
SHIFT = BIT_SHIFT,
|
|
||||||
WIDTH = BIT_SIZE,
|
|
||||||
MASK = (1 << WIDTH) - 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Back reference to containing register
|
* Back reference to containing register
|
||||||
*/
|
*/
|
||||||
typedef Register<OFFSET, storage_t> Compound_reg;
|
typedef Register<OFFSET, STORAGE_T> Compound_reg;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a register value with this subreg set to 'value'
|
|
||||||
* and the rest left zero
|
|
||||||
*/
|
|
||||||
static storage_t bits(storage_t const value)
|
|
||||||
{
|
|
||||||
return (value & MASK) << SHIFT;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of 'SUBREGS' many similar bitregions
|
* An array of 'SUBREGS' many similar bitregions with distance 'BIT_SHIFT'
|
||||||
* FIXME: Side effects of a combination of 'Reg_array' and 'Subreg_array'
|
* FIXME: Side effects of a combination of 'Reg_array' and 'Subreg_array'
|
||||||
* are not evaluated
|
* are not evaluated
|
||||||
*/
|
*/
|
||||||
@ -90,14 +74,14 @@ namespace Genode
|
|||||||
WIDTH = BIT_SIZE,
|
WIDTH = BIT_SIZE,
|
||||||
MASK = (1 << WIDTH) - 1,
|
MASK = (1 << WIDTH) - 1,
|
||||||
ITERATION_WIDTH = (SHIFT + WIDTH),
|
ITERATION_WIDTH = (SHIFT + WIDTH),
|
||||||
STORAGE_WIDTH = BYTE_WIDTH * sizeof(storage_t),
|
STORAGE_WIDTH = BYTE_WIDTH * sizeof(STORAGE_T),
|
||||||
ARRAY_SIZE = (ITERATION_WIDTH * SUBREGS) >> BYTE_EXP,
|
ARRAY_SIZE = (ITERATION_WIDTH * SUBREGS) >> BYTE_EXP,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Back reference to containing register
|
* Back reference to containing register
|
||||||
*/
|
*/
|
||||||
typedef Register<OFFSET, storage_t> Compound_reg;
|
typedef Register<OFFSET, STORAGE_T> Compound_reg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the MMIO-relative offset 'offset' and shift 'shift'
|
* Calculate the MMIO-relative offset 'offset' and shift 'shift'
|
||||||
@ -190,7 +174,7 @@ Genode::Mmio::Register<OFFSET, STORAGE_T>::Subreg_array<BIT_SHIFT, BIT_SIZE, SUB
|
|||||||
unsigned long const index)
|
unsigned long const index)
|
||||||
{
|
{
|
||||||
unsigned long const bit_off = (index+1) * ITERATION_WIDTH - WIDTH;
|
unsigned long const bit_off = (index+1) * ITERATION_WIDTH - WIDTH;
|
||||||
offset = (off_t) ((bit_off / STORAGE_WIDTH) * sizeof(storage_t));
|
offset = (off_t) ((bit_off / STORAGE_WIDTH) * sizeof(STORAGE_T));
|
||||||
shift = bit_off - ( offset << BYTE_EXP );
|
shift = bit_off - ( offset << BYTE_EXP );
|
||||||
offset += Compound_reg::OFFSET;
|
offset += Compound_reg::OFFSET;
|
||||||
}
|
}
|
||||||
@ -325,3 +309,4 @@ void Genode::Mmio::write(typename SUBREG_ARRAY::Compound_reg::storage_t const va
|
|||||||
|
|
||||||
|
|
||||||
#endif /* _BASE__INCLUDE__UTIL__MMIO_H_ */
|
#endif /* _BASE__INCLUDE__UTIL__MMIO_H_ */
|
||||||
|
|
||||||
|
68
base/include/util/register.h
Normal file
68
base/include/util/register.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* \brief Generic accessor framework for highly structured memory regions
|
||||||
|
* \author Martin stein
|
||||||
|
* \date 2011-11-10
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BASE__INCLUDE__UTIL__REGISTER_H_
|
||||||
|
#define _BASE__INCLUDE__UTIL__REGISTER_H_
|
||||||
|
|
||||||
|
#include <base/stdint.h>
|
||||||
|
|
||||||
|
namespace Genode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A POD-like highly structured memory region
|
||||||
|
*/
|
||||||
|
template <typename STORAGE_T>
|
||||||
|
struct Register
|
||||||
|
{
|
||||||
|
typedef STORAGE_T storage_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bitregion within a register
|
||||||
|
*/
|
||||||
|
template <unsigned long BIT_SHIFT, unsigned long BIT_SIZE>
|
||||||
|
struct Subreg
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
SHIFT = BIT_SHIFT,
|
||||||
|
WIDTH = BIT_SIZE,
|
||||||
|
MASK = (1 << WIDTH) - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Back reference to containing register
|
||||||
|
*/
|
||||||
|
typedef Register<storage_t> Compound_reg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a register value with this subreg set to 'value'
|
||||||
|
* and the rest left zero
|
||||||
|
*/
|
||||||
|
static storage_t bits(storage_t const value) { return (value & MASK) << SHIFT; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get value of this subreg from 'reg'
|
||||||
|
*/
|
||||||
|
static storage_t value(storage_t const reg) { return (reg >> SHIFT) & MASK; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get registervalue 'reg' with this subreg set to zero
|
||||||
|
*/
|
||||||
|
static void clear_bits(storage_t & reg) { reg &= ~(MASK << SHIFT); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get registervalue 'reg' with this subreg set to 'value'
|
||||||
|
*/
|
||||||
|
static void set_bits(storage_t & reg, storage_t const value = ~0)
|
||||||
|
{
|
||||||
|
clear_bits(reg);
|
||||||
|
reg |= (value & MASK) << SHIFT;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _BASE__INCLUDE__UTIL__CPU_REGISTER_H_ */
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user