From 9329b91acaef2447d9202d742e92d109b35728d2 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 9 Jan 2012 21:05:49 +0100 Subject: [PATCH] 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. --- base/include/util/mmio.h | 33 +++++------------ base/include/util/register.h | 68 ++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 24 deletions(-) create mode 100644 base/include/util/register.h diff --git a/base/include/util/mmio.h b/base/include/util/mmio.h index d4506fb5e..ae56dab9c 100644 --- a/base/include/util/mmio.h +++ b/base/include/util/mmio.h @@ -7,7 +7,7 @@ #ifndef _BASE__INCLUDE__UTIL__MMIO_H_ #define _BASE__INCLUDE__UTIL__MMIO_H_ -#include +#include namespace Genode @@ -45,40 +45,24 @@ namespace Genode * A POD-like region at offset 'MMIO_OFFSET' within a MMIO region */ template - struct Register + struct Register : public Genode::Register { - typedef STORAGE_T storage_t; enum { OFFSET = MMIO_OFFSET }; /** * A bitregion within a register */ template - struct Subreg + struct Subreg : public Genode::Register::template Subreg { - enum { - SHIFT = BIT_SHIFT, - WIDTH = BIT_SIZE, - MASK = (1 << WIDTH) - 1, - }; - /** * Back reference to containing register */ - typedef Register 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; - }; + typedef Register Compound_reg; }; /** - * 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' * are not evaluated */ @@ -90,14 +74,14 @@ namespace Genode WIDTH = BIT_SIZE, MASK = (1 << WIDTH) - 1, 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, }; /** * Back reference to containing register */ - typedef Register Compound_reg; + typedef Register Compound_reg; /** * Calculate the MMIO-relative offset 'offset' and shift 'shift' @@ -190,7 +174,7 @@ Genode::Mmio::Register::Subreg_array + +namespace Genode +{ + /** + * A POD-like highly structured memory region + */ + template + struct Register + { + typedef STORAGE_T storage_t; + + /** + * A bitregion within a register + */ + template + struct Subreg + { + enum { + SHIFT = BIT_SHIFT, + WIDTH = BIT_SIZE, + MASK = (1 << WIDTH) - 1, + }; + + /** + * Back reference to containing register + */ + typedef Register 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_ */ +