Record device property types

Record device property types, and provide a list of properties at device
registration time.

Add a "device" property type that holds a reference to annother device.

Signed-off-by: Paul Brook <paul@codesourcery.com>
This commit is contained in:
Paul Brook 2009-06-05 15:52:04 +01:00
parent fd93a79999
commit 1431b6a17e
5 changed files with 77 additions and 19 deletions

View file

@ -32,6 +32,7 @@
struct DeviceProperty {
const char *name;
DevicePropType type;
union {
uint64_t i;
void *ptr;
@ -119,13 +120,15 @@ void qdev_free(DeviceState *dev)
free(dev);
}
static DeviceProperty *create_prop(DeviceState *dev, const char *name)
static DeviceProperty *create_prop(DeviceState *dev, const char *name,
DevicePropType type)
{
DeviceProperty *prop;
/* TODO: Check for duplicate properties. */
prop = qemu_mallocz(sizeof(*prop));
prop->name = qemu_strdup(name);
prop->type = type;
prop->next = dev->props;
dev->props = prop;
@ -136,15 +139,23 @@ void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value)
{
DeviceProperty *prop;
prop = create_prop(dev, name);
prop = create_prop(dev, name, PROP_TYPE_INT);
prop->value.i = value;
}
void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value)
{
DeviceProperty *prop;
prop = create_prop(dev, name, PROP_TYPE_DEV);
prop->value.ptr = value;
}
void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value)
{
DeviceProperty *prop;
prop = create_prop(dev, name);
prop = create_prop(dev, name, PROP_TYPE_INT);
prop->value.ptr = value;
}
@ -173,12 +184,14 @@ BusState *qdev_get_parent_bus(DeviceState *dev)
return dev->parent_bus;
}
static DeviceProperty *find_prop(DeviceState *dev, const char *name)
static DeviceProperty *find_prop(DeviceState *dev, const char *name,
DevicePropType type)
{
DeviceProperty *prop;
for (prop = dev->props; prop; prop = prop->next) {
if (strcmp(prop->name, name) == 0) {
assert (prop->type == type);
return prop;
}
}
@ -189,9 +202,10 @@ uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def)
{
DeviceProperty *prop;
prop = find_prop(dev, name);
if (!prop)
prop = find_prop(dev, name, PROP_TYPE_INT);
if (!prop) {
return def;
}
return prop->value.i;
}
@ -200,11 +214,22 @@ void *qdev_get_prop_ptr(DeviceState *dev, const char *name)
{
DeviceProperty *prop;
prop = find_prop(dev, name);
prop = find_prop(dev, name, PROP_TYPE_PTR);
assert(prop);
return prop->value.ptr;
}
DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name)
{
DeviceProperty *prop;
prop = find_prop(dev, name, PROP_TYPE_DEV);
if (!prop) {
return NULL;
}
return prop->value.ptr;
}
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
{
assert(dev->num_gpio_in == 0);

View file

@ -49,6 +49,7 @@ void qdev_free(DeviceState *dev);
/* Set properties between creation and init. */
void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value);
void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value);
void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value);
void qdev_set_netdev(DeviceState *dev, NICInfo *nd);
@ -59,6 +60,17 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
/*** Device API. ***/
typedef enum {
PROP_TYPE_INT,
PROP_TYPE_PTR,
PROP_TYPE_DEV
} DevicePropType;
typedef struct {
const char *name;
DevicePropType type;
} DevicePropList;
typedef struct DeviceInfo DeviceInfo;
typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
@ -68,6 +80,7 @@ typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,
struct DeviceInfo {
qdev_initfn init;
BusType bus_type;
DevicePropList *props;
};
void qdev_register(const char *name, int size, DeviceInfo *info);
@ -83,6 +96,8 @@ CharDriverState *qdev_init_chardev(DeviceState *dev);
BusState *qdev_get_parent_bus(DeviceState *dev);
uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def);
DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name);
/* FIXME: Remove opaque pointer properties. */
void *qdev_get_prop_ptr(DeviceState *dev, const char *name);
/* Convery from a base type to a parent type, with compile time checking. */

View file

@ -226,10 +226,20 @@ static void syborg_timer_init(SysBusDevice *dev)
syborg_timer_save, syborg_timer_load, s);
}
static SysBusDeviceInfo syborg_timer_info = {
.init = syborg_timer_init,
.qdev = {
.props = (DevicePropList[]) {
{.name = "frequency", .type = PROP_TYPE_INT},
{.name = NULL}
}
}
};
static void syborg_timer_register_devices(void)
{
sysbus_register_dev("syborg,timer", sizeof(SyborgTimerState),
syborg_timer_init);
sysbus_register_withprop("syborg,timer", sizeof(SyborgTimerState),
&syborg_timer_info);
}
device_init(syborg_timer_register_devices)

View file

@ -21,11 +21,6 @@
#include "sysbus.h"
#include "sysemu.h"
typedef struct {
DeviceInfo qdev;
sysbus_initfn init;
} SysBusDeviceInfo;
void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
{
assert(n >= 0 && n < dev->num_irq);
@ -109,17 +104,23 @@ static void sysbus_device_init(DeviceState *dev, DeviceInfo *base)
info->init(sysbus_from_qdev(dev));
}
void sysbus_register_withprop(const char *name, size_t size,
SysBusDeviceInfo *info)
{
info->qdev.init = sysbus_device_init;
info->qdev.bus_type = BUS_TYPE_SYSTEM;
assert(size >= sizeof(SysBusDevice));
qdev_register(name, size, &info->qdev);
}
void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
{
SysBusDeviceInfo *info;
info = qemu_mallocz(sizeof(*info));
info->init = init;
info->qdev.init = sysbus_device_init;
info->qdev.bus_type = BUS_TYPE_SYSTEM;
assert(size >= sizeof(SysBusDevice));
qdev_register(name, size, &info->qdev);
sysbus_register_withprop(name, size, info);
}
DeviceState *sysbus_create_varargs(const char *name,

View file

@ -31,7 +31,14 @@ typedef void (*sysbus_initfn)(SysBusDevice *dev);
#define sysbus_from_qdev(dev) ((SysBusDevice *)(dev))
#define FROM_SYSBUS(type, dev) DO_UPCAST(type, busdev, dev)
typedef struct {
DeviceInfo qdev;
sysbus_initfn init;
} SysBusDeviceInfo;
void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init);
void sysbus_register_withprop(const char *name, size_t size,
SysBusDeviceInfo *info);
void *sysbus_new(void);
void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, int iofunc);
void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,