Re: [Qemu-devel] [PATCH v2 06/16] register: QOMify
Le 19/01/2016 23:35, Alistair Francis a écrit : From: Peter CrosthwaiteQOMify 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 Signed-off-by: Alistair Francis --- 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(_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
[Qemu-devel] [PATCH v2 06/16] register: QOMify
From: Peter CrosthwaiteQOMify 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 Signed-off-by: Alistair Francis --- 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(_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 -- 2.5.0