Hi Aditya,
If I understand you right, all you want is to randomly access the
registers by their array index. This is exactly what
'Register_array' was created for. The driver
'base-hw/src/core/pic/imx31.h' gives a good example of how to use
it for plain registers. There you have an array that starts at
MMIO base + 0x20 and spans over 8 registers of 32 bit width each:
struct Nipriority : Register_array<0x20, 32, 8, 32>
{
enum { ALL_LOWEST = 0 };
};
Please note that the second template argument doesn't define the
width of the array items (this is the forth argument) but the
internal access width which affect performance only. Iterative
access is done in this driver later as follows:
for (unsigned i = 0; i < Nipriority::ITEMS; i++)
{
write<Nipriority>(Nipriority::ALL_LOWEST, i);
}
As you can see, you can use the enum 'ITEMS' which is defined by
every 'Register_array' as loop parameter. You can also use
bit-fields inside of register arrays instead of having plain
registers only. The driver 'base-hw/src/core/pic/arm_gic.h' gives
a good example for that:
struct Icfgr : Register_array<0xc00, 32, MAX_INTERRUPT_ID + 1,
2>
{
struct Edge_triggered : Bitfield<1, 1> { };
};
...
for (unsigned i=MIN_SPI; i <= _max_interrupt; i++)
{
_distr.write<Distr::Icfgr::Edge_triggered>(0, i);
...
}
So, here you have a register array 'Icfgr' that starts at MMIO
base + 0xc00 and spans over MAX_INTERRUPT_ID + 1 registers of 2
bit width each. The least significant bit of each register is
unused, but the second bit is defined to be the bit field
'Edge_triggered'. As you can see, the way of accessing
'Edge_triggered' via the register index 'i' is quite intuitive if
you know how to access plain register arrays. I hope this helps
you with your problem. If you have further questions, don't
hesitate to ask ;-)
Cheers,
Martin
On 08.04.2014 13:23, Aditya Kousik wrote:
Hello Martin,
Truth be told, I didn't want to probe
the use of an object myself. But, if I
want to create an array of registers
that can be iteratively called, it saves
a lot of effort as opposed to manually
writing register by register. Since
write <..> involves explicit
'register_name' here. I'm not sure (or I
may not know how) if I can create an
array of Mmio::Register's since
declaration to Register necessitates an
offset and access width.
Normally, my initial attempt was to create
an array of addresses that pointed to the
starting address of the registers. This
gives us random access and ability to put
R/W accesses in a loop. But it is very
primitive and does not use the access_t
concept.
But then, as you've said I looked into
Register_array a bit deeper. Here is an
approach I've thought of.
Define all registers with offset values.
Then, define a Register_array, say R_array
that has an offset to the first defined
register, number of items = number of
registers. This works given the registers in
between are all of the same size
(obviously). If there are N registers
defined, then write<R_array>(value,
idx) should write to the ith register
defined, right? Not necessarily.
Consider this.
class Foo : Mmio
{
struct reg1 : Register<0x0, 32> { };
struct reg2: Register<0x4, 32> { };
struct reg3: Register<0x10, 32> { };
struct reg4: Register<0x4c, 32> { };
struct reg_array : Register_array<0x0,
32,32,4> { };
public:
void write_to_regs()
{
write<reg1>(0);
write<reg4>(0xff);
}
};
Will I achieve random access to the
registers with the use of the register array?
No. Unless, I am fundamentally wrong her, in
which case, I'd be glad to know where I'm
going wrong.
Thanks and regards
Aditya.
------------------------------------------------------------------------------
Put Bad Developers to Shame
Dominate Development with Jenkins Continuous Integration
Continuously Automate Build, Test & Deployment
Start a new project now. Try Jenkins in the cloud.
http://p.sf.net/sfu/13600_Cloudbees
_______________________________________________
Genode-main mailing list
Genode-main@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/genode-main