On Thu, Jun 9, 2016 at 6:08 AM, KONRAD Frederic <[email protected]> wrote: > Hi Alistair, > > > Le 13/05/2016 à 00:45, Alistair Francis a écrit : >> >> 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. >> >> This patch also adds the RegisterInfoArray struct, which allows all of >> the individual RegisterInfo structs to be grouped into a single memory >> region. >> >> Signed-off-by: Peter Crosthwaite <[email protected]> >> Signed-off-by: Alistair Francis <[email protected]> >> --- >> V6: >> - Add the memory region later >> V5: >> - Convert to using only one memory region >> >> hw/core/register.c | 72 >> +++++++++++++++++++++++++++++++++++++++++++++++++++ >> include/hw/register.h | 50 +++++++++++++++++++++++++++++++++++ >> 2 files changed, 122 insertions(+) >> >> diff --git a/hw/core/register.c b/hw/core/register.c >> index 5e6f621..25196e6 100644 >> --- a/hw/core/register.c >> +++ b/hw/core/register.c >> @@ -147,3 +147,75 @@ 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) >> +{ >> + RegisterInfoArray *reg_array = opaque; >> + RegisterInfo *reg = NULL; >> + uint64_t we = ~0; >> + int i, shift = 0; >> + >> + for (i = 0; i < reg_array->num_elements; i++) { >> + if (reg_array->r[i]->access->decode.addr == addr) { >> + reg = reg_array->r[i]; >> + break; >> + } >> + } >> + assert(reg); >> + >> + /* Generate appropriate write enable mask and shift values */ >> + if (reg->data_size < size) { >> + we = MAKE_64BIT_MASK(0, reg->data_size * 8); >> + shift = 8 * (be ? reg->data_size - size : 0); >> + } else if (reg->data_size >= size) { >> + we = MAKE_64BIT_MASK(0, size * 8); >> + } >> + >> + register_write(reg, value << shift, we << shift, reg_array->prefix, >> + reg_array->debug); >> +} >> + >> +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) >> +{ >> + RegisterInfoArray *reg_array = opaque; >> + RegisterInfo *reg = NULL; >> + int i, shift; >> + >> + for (i = 0; i < reg_array->num_elements; i++) { >> + if (reg_array->r[i]->access->decode.addr == addr) { >> + reg = reg_array->r[i]; >> + break; >> + } >> + } >> + assert(reg); >> + >> + shift = 8 * (be ? reg->data_size - size : 0); >> + >> + return (register_read(reg, reg_array->prefix, reg_array->debug) >> >> shift) & >> + MAKE_64BIT_MASK(0, size * 8); >> +} >> + >> +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 07d0616..786707b 100644 >> --- a/include/hw/register.h >> +++ b/include/hw/register.h >> @@ -15,6 +15,7 @@ >> >> typedef struct RegisterInfo RegisterInfo; >> typedef struct RegisterAccessInfo RegisterAccessInfo; >> +typedef struct RegisterInfoArray RegisterInfoArray; >> >> /** >> * Access description for a register that is part of guest accessible >> device >> @@ -51,6 +52,10 @@ struct RegisterAccessInfo { >> void (*post_write)(RegisterInfo *reg, uint64_t val); >> >> uint64_t (*post_read)(RegisterInfo *reg, uint64_t val); >> + >> + struct { >> + hwaddr addr; >> + } decode; > > > Is there any reason why there is a struct here?
I think it is just left over, I have removed it. Thanks, Alistair > > Fred
