mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 16:35:28 +00:00
parent
89109cf377
commit
028ef7d776
@ -207,9 +207,9 @@ namespace Genode
|
||||
* targeted by 'offset'.
|
||||
* \param index index of the targeted array item
|
||||
*/
|
||||
static inline void access_dest(off_t & offset,
|
||||
unsigned long & shift,
|
||||
unsigned long const index)
|
||||
static inline void dst(off_t & offset,
|
||||
unsigned long & shift,
|
||||
unsigned long const index)
|
||||
{
|
||||
unsigned long const bit_off = index << ITEM_WIDTH_LOG2;
|
||||
offset = (off_t) ((bit_off >> BYTE_WIDTH_LOG2)
|
||||
@ -217,6 +217,20 @@ namespace Genode
|
||||
shift = bit_off - ( offset << BYTE_WIDTH_LOG2 );
|
||||
offset += OFFSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calc destination of a simple array-item access without shift
|
||||
*
|
||||
* \param offset gets overridden with the offset of the the
|
||||
* access destination, relative to the MMIO base
|
||||
* \param index index of the targeted array item
|
||||
*/
|
||||
static inline void simple_dst(off_t & offset,
|
||||
unsigned long const index)
|
||||
{
|
||||
offset = (index << ITEM_WIDTH_LOG2) >> BYTE_WIDTH_LOG2;
|
||||
offset += OFFSET;
|
||||
}
|
||||
};
|
||||
|
||||
addr_t const base; /* base address of targeted MMIO region */
|
||||
@ -337,13 +351,13 @@ namespace Genode
|
||||
/* if item width equals access width we optimize the access */
|
||||
off_t offset;
|
||||
if (Array::ITEM_WIDTH == Array::ACCESS_WIDTH) {
|
||||
offset = Array::OFFSET + (index << Array::ITEM_WIDTH_LOG2);
|
||||
Array::simple_dst(offset, index);
|
||||
return _read<access_t>(offset);
|
||||
|
||||
/* access width and item width differ */
|
||||
} else {
|
||||
long unsigned shift;
|
||||
Array::access_dest(offset, shift, index);
|
||||
Array::dst(offset, shift, index);
|
||||
return (_read<access_t>(offset) >> shift) &
|
||||
Array::ITEM_MASK;
|
||||
}
|
||||
@ -369,14 +383,13 @@ namespace Genode
|
||||
/* optimize the access if item width equals access width */
|
||||
off_t offset;
|
||||
if (Array::ITEM_WIDTH == Array::ACCESS_WIDTH) {
|
||||
offset = Array::OFFSET +
|
||||
(index << Array::ITEM_WIDTH_LOG2);
|
||||
Array::simple_dst(offset, index);
|
||||
_write<access_t>(offset, value);
|
||||
|
||||
/* access width and item width differ */
|
||||
} else {
|
||||
long unsigned shift;
|
||||
Array::access_dest(offset, shift, index);
|
||||
Array::dst(offset, shift, index);
|
||||
|
||||
/* insert new value into old register value */
|
||||
access_t write_value;
|
||||
|
@ -110,6 +110,10 @@ struct Test_mmio : public Mmio
|
||||
struct B : Bitfield<2,4> { };
|
||||
};
|
||||
|
||||
struct Simple_array_1 : Register_array<0x0, 32, 2, 32> { };
|
||||
|
||||
struct Simple_array_2 : Register_array<0x2, 16, 4, 16> { };
|
||||
|
||||
struct Strict_reg : Register<0x0, 32, true>
|
||||
{
|
||||
struct A : Bitfield<3,2> { };
|
||||
@ -400,6 +404,20 @@ int main()
|
||||
if (compare_mem(mmio_mem, mmio_cmpr_15, sizeof(mmio_mem))) {
|
||||
return test_failed(15); }
|
||||
|
||||
/**
|
||||
* Test 16, writing to simple register array
|
||||
*/
|
||||
zero_mem(mmio_mem, sizeof(mmio_mem));
|
||||
*(uint8_t*)((addr_t)mmio_mem + sizeof(uint16_t)) = 0xaa;
|
||||
mmio.write<Test_mmio::Simple_array_1>(0x12345678, 0);
|
||||
mmio.write<Test_mmio::Simple_array_1>(0x87654321, 1);
|
||||
|
||||
mmio.write<Test_mmio::Simple_array_2>(0xfedc, 0);
|
||||
mmio.write<Test_mmio::Simple_array_2>(0xabcd, 2);
|
||||
static uint8_t mmio_cmpr_16[MMIO_SIZE] = {0x78,0x56,0xdc,0xfe,0x21,0x43,0xcd,0xab};
|
||||
if (compare_mem(mmio_mem, mmio_cmpr_16, sizeof(mmio_mem))) {
|
||||
return test_failed(16); }
|
||||
|
||||
printf("Test done\n");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user