summaryrefslogtreecommitdiffstats
path: root/hw/core/register.c
diff options
context:
space:
mode:
authorAlistair Francis2016-07-04 14:06:36 +0200
committerPeter Maydell2016-07-04 14:15:22 +0200
commit0b73c9bb066c6b66a9466ad9c3bbfd841477bf50 (patch)
tree50a4c0cc35fa6e6c1a1b8e0813370ef7a3ff0bad /hw/core/register.c
parentregister: Add Register API (diff)
downloadqemu-0b73c9bb066c6b66a9466ad9c3bbfd841477bf50.tar.gz
qemu-0b73c9bb066c6b66a9466ad9c3bbfd841477bf50.tar.xz
qemu-0b73c9bb066c6b66a9466ad9c3bbfd841477bf50.zip
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>
Diffstat (limited to 'hw/core/register.c')
-rw-r--r--hw/core/register.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/hw/core/register.c b/hw/core/register.c
index 033b03c438..f7f63389d2 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -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);
+}