register: Add Memory API glue

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 <peter.crosthwaite@xilinx.com>
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Message-id: f7704d8ac6ac0f469ed35401f8151a38bd01468b.1467053537.git.alistair.francis@xilinx.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Alistair Francis 2016-07-04 13:06:36 +01:00 committed by Peter Maydell
parent 1599121b57
commit 0b73c9bb06
2 changed files with 102 additions and 0 deletions

View file

@ -158,3 +158,62 @@ void register_reset(RegisterInfo *reg)
register_write_val(reg, reg->access->reset);
}
void register_write_memory(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
RegisterInfoArray *reg_array = opaque;
RegisterInfo *reg = NULL;
uint64_t we;
int i;
for (i = 0; i < reg_array->num_elements; i++) {
if (reg_array->r[i]->access->addr == addr) {
reg = reg_array->r[i];
break;
}
}
if (!reg) {
qemu_log_mask(LOG_GUEST_ERROR, "Write to unimplemented register at " \
"address: %#" PRIx64 "\n", addr);
return;
}
/* Generate appropriate write enable mask */
if (reg->data_size < size) {
we = MAKE_64BIT_MASK(0, reg->data_size * 8);
} else {
we = MAKE_64BIT_MASK(0, size * 8);
}
register_write(reg, value, we, reg_array->prefix,
reg_array->debug);
}
uint64_t register_read_memory(void *opaque, hwaddr addr,
unsigned size)
{
RegisterInfoArray *reg_array = opaque;
RegisterInfo *reg = NULL;
uint64_t read_val;
int i;
for (i = 0; i < reg_array->num_elements; i++) {
if (reg_array->r[i]->access->addr == addr) {
reg = reg_array->r[i];
break;
}
}
if (!reg) {
qemu_log_mask(LOG_GUEST_ERROR, "Read to unimplemented register at " \
"address: %#" PRIx64 "\n", addr);
return 0;
}
read_val = register_read(reg, size * 8, reg_array->prefix,
reg_array->debug);
return extract64(read_val, 0, size * 8);
}