Le 19/01/2016 23:35, Alistair Francis a écrit :
From: Peter Crosthwaite <peter.crosthwa...@xilinx.com>
QOMify registers as a child of TYPE_DEVICE. This allows registers to
define GPIOs.
Define an init helper that will do QOM initialisation as well as setup
the r/w fast paths.
Signed-off-by: Peter Crosthwaite <peter.crosthwa...@xilinx.com>
Signed-off-by: Alistair Francis <alistair.fran...@xilinx.com>
---
hw/core/register.c | 34 ++++++++++++++++++++++++++++++++++
include/hw/register.h | 17 +++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/hw/core/register.c b/hw/core/register.c
index ca10cff..000b87f 100644
--- a/hw/core/register.c
+++ b/hw/core/register.c
@@ -185,6 +185,28 @@ void register_reset(RegisterInfo *reg)
register_write_val(reg, reg->access->reset);
}
+void register_init(RegisterInfo *reg)
+{
+ assert(reg);
+ const RegisterAccessInfo *ac;
+
+ if (!reg->data || !reg->access) {
+ return;
+ }
+
+ object_initialize((void *)reg, sizeof(*reg), TYPE_REGISTER);
+
+ ac = reg->access;
+
+ /* if there are no debug msgs and no RMW requirement, mark for fast write
*/
+ reg->write_lite = reg->debug || ac->ro || ac->w1c || ac->pre_write ||
+ ((ac->ge0 || ac->ge1) && qemu_loglevel_mask(LOG_GUEST_ERROR)) ||
+ ((ac->ui0 || ac->ui1) && qemu_loglevel_mask(LOG_UNIMP))
+ ? false : true;
+ /* no debug and no clear-on-read is a fast read */
+ reg->read_lite = reg->debug || ac->cor ? false : true;
+}
+
static inline void register_write_memory(void *opaque, hwaddr addr,
uint64_t value, unsigned size, bool
be)
{
@@ -232,3 +254,15 @@ uint64_t register_read_memory_le(void *opaque, hwaddr
addr, unsigned size)
{
return register_read_memory(opaque, addr, size, false);
}
+
+static const TypeInfo register_info = {
+ .name = TYPE_REGISTER,
+ .parent = TYPE_DEVICE,
+};
+
+static void register_register_types(void)
+{
+ type_register_static(®ister_info);
+}
+
+type_init(register_register_types)
diff --git a/include/hw/register.h b/include/hw/register.h
index 0c6f03d..6677dee 100644
--- a/include/hw/register.h
+++ b/include/hw/register.h
@@ -11,6 +11,7 @@
#ifndef REGISTER_H
#define REGISTER_H
+#include "hw/qdev-core.h"
#include "exec/memory.h"
typedef struct RegisterInfo RegisterInfo;
@@ -101,6 +102,11 @@ struct RegisterAccessInfo {
*/
struct RegisterInfo {
+ /*< private >*/
+ DeviceState parent_obj;
+
+ /*< public >*/
+
void *data;
int data_size;
@@ -119,6 +125,9 @@ struct RegisterInfo {
MemoryRegion mem;
};
+#define TYPE_REGISTER "qemu,register"
+#define REGISTER(obj) OBJECT_CHECK(RegisterInfo, (obj), TYPE_REGISTER)
+
/**
* write a value to a register, subject to its restrictions
* @reg: register to write to
@@ -144,6 +153,14 @@ uint64_t register_read(RegisterInfo *reg);
void register_reset(RegisterInfo *reg);
/**
+ * Initialize a register. GPIO's are setup as IOs to the specified device.
+ * Fast paths for eligible registers are enabled.
+ * @reg: Register to initialize
+ */
+
+void register_init(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
seems ok to me
Reviewed-by: KONRAD Frederic <fred.kon...@greensocs.com>
Fred