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'.
|
* targeted by 'offset'.
|
||||||
* \param index index of the targeted array item
|
* \param index index of the targeted array item
|
||||||
*/
|
*/
|
||||||
static inline void access_dest(off_t & offset,
|
static inline void dst(off_t & offset,
|
||||||
unsigned long & shift,
|
unsigned long & shift,
|
||||||
unsigned long const index)
|
unsigned long const index)
|
||||||
{
|
{
|
||||||
unsigned long const bit_off = index << ITEM_WIDTH_LOG2;
|
unsigned long const bit_off = index << ITEM_WIDTH_LOG2;
|
||||||
offset = (off_t) ((bit_off >> BYTE_WIDTH_LOG2)
|
offset = (off_t) ((bit_off >> BYTE_WIDTH_LOG2)
|
||||||
@ -217,6 +217,20 @@ namespace Genode
|
|||||||
shift = bit_off - ( offset << BYTE_WIDTH_LOG2 );
|
shift = bit_off - ( offset << BYTE_WIDTH_LOG2 );
|
||||||
offset += OFFSET;
|
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 */
|
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 */
|
/* if item width equals access width we optimize the access */
|
||||||
off_t offset;
|
off_t offset;
|
||||||
if (Array::ITEM_WIDTH == Array::ACCESS_WIDTH) {
|
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);
|
return _read<access_t>(offset);
|
||||||
|
|
||||||
/* access width and item width differ */
|
/* access width and item width differ */
|
||||||
} else {
|
} else {
|
||||||
long unsigned shift;
|
long unsigned shift;
|
||||||
Array::access_dest(offset, shift, index);
|
Array::dst(offset, shift, index);
|
||||||
return (_read<access_t>(offset) >> shift) &
|
return (_read<access_t>(offset) >> shift) &
|
||||||
Array::ITEM_MASK;
|
Array::ITEM_MASK;
|
||||||
}
|
}
|
||||||
@ -369,14 +383,13 @@ namespace Genode
|
|||||||
/* optimize the access if item width equals access width */
|
/* optimize the access if item width equals access width */
|
||||||
off_t offset;
|
off_t offset;
|
||||||
if (Array::ITEM_WIDTH == Array::ACCESS_WIDTH) {
|
if (Array::ITEM_WIDTH == Array::ACCESS_WIDTH) {
|
||||||
offset = Array::OFFSET +
|
Array::simple_dst(offset, index);
|
||||||
(index << Array::ITEM_WIDTH_LOG2);
|
|
||||||
_write<access_t>(offset, value);
|
_write<access_t>(offset, value);
|
||||||
|
|
||||||
/* access width and item width differ */
|
/* access width and item width differ */
|
||||||
} else {
|
} else {
|
||||||
long unsigned shift;
|
long unsigned shift;
|
||||||
Array::access_dest(offset, shift, index);
|
Array::dst(offset, shift, index);
|
||||||
|
|
||||||
/* insert new value into old register value */
|
/* insert new value into old register value */
|
||||||
access_t write_value;
|
access_t write_value;
|
||||||
|
@ -110,6 +110,10 @@ struct Test_mmio : public Mmio
|
|||||||
struct B : Bitfield<2,4> { };
|
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 Strict_reg : Register<0x0, 32, true>
|
||||||
{
|
{
|
||||||
struct A : Bitfield<3,2> { };
|
struct A : Bitfield<3,2> { };
|
||||||
@ -400,6 +404,20 @@ int main()
|
|||||||
if (compare_mem(mmio_mem, mmio_cmpr_15, sizeof(mmio_mem))) {
|
if (compare_mem(mmio_mem, mmio_cmpr_15, sizeof(mmio_mem))) {
|
||||||
return test_failed(15); }
|
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");
|
printf("Test done\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user