On Wed, Jan 27, 2016 at 6:51 AM, KONRAD Frederic <fred.kon...@greensocs.com> wrote: > > > Le 19/01/2016 23:35, Alistair Francis a écrit : >> >> From: Peter Crosthwaite <peter.crosthwa...@xilinx.com> >> >> Add memory io handlers that glue the register API to the memory API. >> Just translation functions at this stage. Although it does allow for >> devices to be created without all-in-one mmio r/w handlers. >> >> Signed-off-by: Peter Crosthwaite <peter.crosthwa...@xilinx.com> >> Signed-off-by: Alistair Francis <alistair.fran...@xilinx.com> >> --- >> changed from v2: >> Added fast path to register_write_memory to skip endianness bitbashing >> >> hw/core/register.c | 48 >> ++++++++++++++++++++++++++++++++++++++++++++++++ >> include/hw/register.h | 30 ++++++++++++++++++++++++++++++ >> 2 files changed, 78 insertions(+) >> >> diff --git a/hw/core/register.c b/hw/core/register.c >> index 02a4376..ca10cff 100644 >> --- a/hw/core/register.c >> +++ b/hw/core/register.c >> @@ -184,3 +184,51 @@ void register_reset(RegisterInfo *reg) >> register_write_val(reg, reg->access->reset); >> } >> + >> +static inline void register_write_memory(void *opaque, hwaddr addr, >> + uint64_t value, unsigned size, >> bool be) >> +{ >> + RegisterInfo *reg = opaque; > > Doesn't that need the QOM REGISTER(obj) conversion defined in patch 6?
It shouldn't. Looking at other devices they don't use the cast macro for the opaque data to read/write functions. Thanks, Alistair > > Fred > >> + uint64_t we = ~0; >> + int shift = 0; >> + >> + if (reg->data_size != size) { >> + we = (size == 8) ? ~0ull : (1ull << size * 8) - 1; >> + shift = 8 * (be ? reg->data_size - size - addr : addr); >> + } >> + >> + assert(size + addr <= reg->data_size); >> + register_write(reg, value << shift, we << shift); >> +} >> + >> +void register_write_memory_be(void *opaque, hwaddr addr, uint64_t value, >> + unsigned size) >> +{ >> + register_write_memory(opaque, addr, value, size, true); >> +} >> + >> + >> +void register_write_memory_le(void *opaque, hwaddr addr, uint64_t value, >> + unsigned size) >> +{ >> + register_write_memory(opaque, addr, value, size, false); >> +} >> + >> +static inline uint64_t register_read_memory(void *opaque, hwaddr addr, >> + unsigned size, bool be) >> +{ >> + RegisterInfo *reg = opaque; >> + int shift = 8 * (be ? reg->data_size - size - addr : addr); >> + >> + return register_read(reg) >> shift; >> +} >> + >> +uint64_t register_read_memory_be(void *opaque, hwaddr addr, unsigned >> size) >> +{ >> + return register_read_memory(opaque, addr, size, true); >> +} >> + >> +uint64_t register_read_memory_le(void *opaque, hwaddr addr, unsigned >> size) >> +{ >> + return register_read_memory(opaque, addr, size, false); >> +} >> diff --git a/include/hw/register.h b/include/hw/register.h >> index 249f458..a3c41db 100644 >> --- a/include/hw/register.h >> +++ b/include/hw/register.h >> @@ -86,6 +86,8 @@ struct RegisterAccessInfo { >> * @prefix: String prefix for log and debug messages >> * >> * @opaque: Opaque data for the register >> + * >> + * @mem: optional Memory region for the register >> */ >> struct RegisterInfo { >> @@ -103,6 +105,8 @@ struct RegisterInfo { >> bool read_lite; >> bool write_lite; >> + >> + MemoryRegion mem; >> }; >> /** >> @@ -129,4 +133,30 @@ uint64_t register_read(RegisterInfo *reg); >> void register_reset(RegisterInfo *reg); >> +/** >> + * Memory API MMIO write handler that will write to a Register API >> register. >> + * _be for big endian variant and _le for little endian. >> + * @opaque: RegisterInfo to write to >> + * @addr: Address to write >> + * @value: Value to write >> + * @size: Number of bytes to write >> + */ >> + >> +void register_write_memory_be(void *opaque, hwaddr addr, uint64_t value, >> + unsigned size); >> +void register_write_memory_le(void *opaque, hwaddr addr, uint64_t value, >> + unsigned size); >> + >> +/** >> + * Memory API MMIO read handler that will read from a Register API >> register. >> + * _be for big endian variant and _le for little endian. >> + * @opaque: RegisterInfo to read from >> + * @addr: Address to read >> + * @size: Number of bytes to read >> + * returns: Value read from register >> + */ >> + >> +uint64_t register_read_memory_be(void *opaque, hwaddr addr, unsigned >> size); >> +uint64_t register_read_memory_le(void *opaque, hwaddr addr, unsigned >> size); >> + >> #endif > > >