mirror of
https://github.com/qemu/qemu.git
synced 2024-11-26 12:23:36 +08:00
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:
parent
1599121b57
commit
0b73c9bb06
@ -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);
|
||||
}
|
||||
|
@ -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,8 @@ struct RegisterAccessInfo {
|
||||
void (*post_write)(RegisterInfo *reg, uint64_t val);
|
||||
|
||||
uint64_t (*post_read)(RegisterInfo *reg, uint64_t val);
|
||||
|
||||
hwaddr addr;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -78,6 +81,25 @@ struct RegisterInfo {
|
||||
void *opaque;
|
||||
};
|
||||
|
||||
/**
|
||||
* This structure is used to group all of the individual registers which are
|
||||
* modeled using the RegisterInfo structure.
|
||||
*
|
||||
* @r is an aray containing of all the relevent RegisterInfo structures.
|
||||
*
|
||||
* @num_elements is the number of elements in the array r
|
||||
*
|
||||
* @mem: optional Memory region for the register
|
||||
*/
|
||||
|
||||
struct RegisterInfoArray {
|
||||
int num_elements;
|
||||
RegisterInfo **r;
|
||||
|
||||
bool debug;
|
||||
const char *prefix;
|
||||
};
|
||||
|
||||
/**
|
||||
* write a value to a register, subject to its restrictions
|
||||
* @reg: register to write to
|
||||
@ -109,4 +131,25 @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
|
||||
|
||||
void register_reset(RegisterInfo *reg);
|
||||
|
||||
/**
|
||||
* Memory API MMIO write handler that will write to a Register API register.
|
||||
* @opaque: RegisterInfo to write to
|
||||
* @addr: Address to write
|
||||
* @value: Value to write
|
||||
* @size: Number of bytes to write
|
||||
*/
|
||||
|
||||
void register_write_memory(void *opaque, hwaddr addr, uint64_t value,
|
||||
unsigned size);
|
||||
|
||||
/**
|
||||
* Memory API MMIO read handler that will read from a Register API register.
|
||||
* @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(void *opaque, hwaddr addr, unsigned size);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user