mirror of https://github.com/xqemu/xqemu.git
i8254: Convert PITCommonState to QOM realizefn
Instead of having the parent provide PITCommonClass::init, let the children override DeviceClass::realize themselves. This pushes the responsibility for saving and calling the parent's realizefn to the children. Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
parent
58cd986422
commit
a15d09127b
|
@ -33,6 +33,10 @@
|
||||||
#define CALIBRATION_ROUNDS 3
|
#define CALIBRATION_ROUNDS 3
|
||||||
|
|
||||||
#define KVM_PIT(obj) OBJECT_CHECK(KVMPITState, (obj), TYPE_KVM_I8254)
|
#define KVM_PIT(obj) OBJECT_CHECK(KVMPITState, (obj), TYPE_KVM_I8254)
|
||||||
|
#define KVM_PIT_CLASS(class) \
|
||||||
|
OBJECT_CLASS_CHECK(KVMPITClass, (class), TYPE_KVM_I8254)
|
||||||
|
#define KVM_PIT_GET_CLASS(obj) \
|
||||||
|
OBJECT_GET_CLASS(KVMPITClass, (obj), TYPE_KVM_I8254)
|
||||||
|
|
||||||
typedef struct KVMPITState {
|
typedef struct KVMPITState {
|
||||||
PITCommonState parent_obj;
|
PITCommonState parent_obj;
|
||||||
|
@ -42,6 +46,12 @@ typedef struct KVMPITState {
|
||||||
int64_t kernel_clock_offset;
|
int64_t kernel_clock_offset;
|
||||||
} KVMPITState;
|
} KVMPITState;
|
||||||
|
|
||||||
|
typedef struct KVMPITClass {
|
||||||
|
PITCommonClass parent_class;
|
||||||
|
|
||||||
|
DeviceRealize parent_realize;
|
||||||
|
} KVMPITClass;
|
||||||
|
|
||||||
static int64_t abs64(int64_t v)
|
static int64_t abs64(int64_t v)
|
||||||
{
|
{
|
||||||
return v < 0 ? -v : v;
|
return v < 0 ? -v : v;
|
||||||
|
@ -237,8 +247,10 @@ static void kvm_pit_vm_state_change(void *opaque, int running,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kvm_pit_initfn(PITCommonState *pit)
|
static void kvm_pit_realizefn(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
|
PITCommonState *pit = PIT_COMMON(dev);
|
||||||
|
KVMPITClass *kpc = KVM_PIT_GET_CLASS(dev);
|
||||||
KVMPITState *s = KVM_PIT(pit);
|
KVMPITState *s = KVM_PIT(pit);
|
||||||
struct kvm_pit_config config = {
|
struct kvm_pit_config config = {
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
|
@ -251,9 +263,9 @@ static int kvm_pit_initfn(PITCommonState *pit)
|
||||||
ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT);
|
ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT);
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Create kernel PIC irqchip failed: %s\n",
|
error_setg(errp, "Create kernel PIC irqchip failed: %s",
|
||||||
strerror(ret));
|
strerror(ret));
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
switch (s->lost_tick_policy) {
|
switch (s->lost_tick_policy) {
|
||||||
case LOST_TICK_DELAY:
|
case LOST_TICK_DELAY:
|
||||||
|
@ -264,24 +276,25 @@ static int kvm_pit_initfn(PITCommonState *pit)
|
||||||
|
|
||||||
ret = kvm_vm_ioctl(kvm_state, KVM_REINJECT_CONTROL, &control);
|
ret = kvm_vm_ioctl(kvm_state, KVM_REINJECT_CONTROL, &control);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr,
|
error_setg(errp,
|
||||||
"Can't disable in-kernel PIT reinjection: %s\n",
|
"Can't disable in-kernel PIT reinjection: %s",
|
||||||
strerror(ret));
|
strerror(ret));
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
error_setg(errp, "Lost tick policy not supported.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_region_init_reservation(&pit->ioports, "kvm-pit", 4);
|
memory_region_init_reservation(&pit->ioports, "kvm-pit", 4);
|
||||||
|
|
||||||
qdev_init_gpio_in(&pit->dev.qdev, kvm_pit_irq_control, 1);
|
qdev_init_gpio_in(dev, kvm_pit_irq_control, 1);
|
||||||
|
|
||||||
qemu_add_vm_change_state_handler(kvm_pit_vm_state_change, s);
|
qemu_add_vm_change_state_handler(kvm_pit_vm_state_change, s);
|
||||||
|
|
||||||
return 0;
|
kpc->parent_realize(dev, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property kvm_pit_properties[] = {
|
static Property kvm_pit_properties[] = {
|
||||||
|
@ -293,10 +306,12 @@ static Property kvm_pit_properties[] = {
|
||||||
|
|
||||||
static void kvm_pit_class_init(ObjectClass *klass, void *data)
|
static void kvm_pit_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
|
KVMPITClass *kpc = KVM_PIT_CLASS(klass);
|
||||||
PITCommonClass *k = PIT_COMMON_CLASS(klass);
|
PITCommonClass *k = PIT_COMMON_CLASS(klass);
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
|
||||||
k->init = kvm_pit_initfn;
|
kpc->parent_realize = dc->realize;
|
||||||
|
dc->realize = kvm_pit_realizefn;
|
||||||
k->set_channel_gate = kvm_pit_set_gate;
|
k->set_channel_gate = kvm_pit_set_gate;
|
||||||
k->get_channel_info = kvm_pit_get_channel_info;
|
k->get_channel_info = kvm_pit_get_channel_info;
|
||||||
k->pre_save = kvm_pit_get;
|
k->pre_save = kvm_pit_get;
|
||||||
|
@ -310,6 +325,7 @@ static const TypeInfo kvm_pit_info = {
|
||||||
.parent = TYPE_PIT_COMMON,
|
.parent = TYPE_PIT_COMMON,
|
||||||
.instance_size = sizeof(KVMPITState),
|
.instance_size = sizeof(KVMPITState),
|
||||||
.class_init = kvm_pit_class_init,
|
.class_init = kvm_pit_class_init,
|
||||||
|
.class_size = sizeof(KVMPITClass),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void kvm_pit_register(void)
|
static void kvm_pit_register(void)
|
||||||
|
|
|
@ -35,6 +35,15 @@
|
||||||
#define RW_STATE_WORD0 3
|
#define RW_STATE_WORD0 3
|
||||||
#define RW_STATE_WORD1 4
|
#define RW_STATE_WORD1 4
|
||||||
|
|
||||||
|
#define PIT_CLASS(class) OBJECT_CLASS_CHECK(PITClass, (class), TYPE_I8254)
|
||||||
|
#define PIT_GET_CLASS(obj) OBJECT_GET_CLASS(PITClass, (obj), TYPE_I8254)
|
||||||
|
|
||||||
|
typedef struct PITClass {
|
||||||
|
PITCommonClass parent_class;
|
||||||
|
|
||||||
|
DeviceRealize parent_realize;
|
||||||
|
} PITClass;
|
||||||
|
|
||||||
static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
|
static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
|
||||||
|
|
||||||
static int pit_get_count(PITChannelState *s)
|
static int pit_get_count(PITChannelState *s)
|
||||||
|
@ -313,20 +322,22 @@ static void pit_post_load(PITCommonState *s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pit_initfn(PITCommonState *pit)
|
static void pit_realizefn(DeviceState *dev, Error **err)
|
||||||
{
|
{
|
||||||
|
PITCommonState *pit = PIT_COMMON(dev);
|
||||||
|
PITClass *pc = PIT_GET_CLASS(dev);
|
||||||
PITChannelState *s;
|
PITChannelState *s;
|
||||||
|
|
||||||
s = &pit->channels[0];
|
s = &pit->channels[0];
|
||||||
/* the timer 0 is connected to an IRQ */
|
/* the timer 0 is connected to an IRQ */
|
||||||
s->irq_timer = qemu_new_timer_ns(vm_clock, pit_irq_timer, s);
|
s->irq_timer = qemu_new_timer_ns(vm_clock, pit_irq_timer, s);
|
||||||
qdev_init_gpio_out(&pit->dev.qdev, &s->irq, 1);
|
qdev_init_gpio_out(dev, &s->irq, 1);
|
||||||
|
|
||||||
memory_region_init_io(&pit->ioports, &pit_ioport_ops, pit, "pit", 4);
|
memory_region_init_io(&pit->ioports, &pit_ioport_ops, pit, "pit", 4);
|
||||||
|
|
||||||
qdev_init_gpio_in(&pit->dev.qdev, pit_irq_control, 1);
|
qdev_init_gpio_in(dev, pit_irq_control, 1);
|
||||||
|
|
||||||
return 0;
|
pc->parent_realize(dev, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property pit_properties[] = {
|
static Property pit_properties[] = {
|
||||||
|
@ -336,10 +347,12 @@ static Property pit_properties[] = {
|
||||||
|
|
||||||
static void pit_class_initfn(ObjectClass *klass, void *data)
|
static void pit_class_initfn(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
|
PITClass *pc = PIT_CLASS(klass);
|
||||||
PITCommonClass *k = PIT_COMMON_CLASS(klass);
|
PITCommonClass *k = PIT_COMMON_CLASS(klass);
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
|
||||||
k->init = pit_initfn;
|
pc->parent_realize = dc->realize;
|
||||||
|
dc->realize = pit_realizefn;
|
||||||
k->set_channel_gate = pit_set_channel_gate;
|
k->set_channel_gate = pit_set_channel_gate;
|
||||||
k->get_channel_info = pit_get_channel_info_common;
|
k->get_channel_info = pit_get_channel_info_common;
|
||||||
k->post_load = pit_post_load;
|
k->post_load = pit_post_load;
|
||||||
|
@ -352,6 +365,7 @@ static const TypeInfo pit_info = {
|
||||||
.parent = TYPE_PIT_COMMON,
|
.parent = TYPE_PIT_COMMON,
|
||||||
.instance_size = sizeof(PITCommonState),
|
.instance_size = sizeof(PITCommonState),
|
||||||
.class_init = pit_class_initfn,
|
.class_init = pit_class_initfn,
|
||||||
|
.class_size = sizeof(PITClass),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pit_register_types(void)
|
static void pit_register_types(void)
|
||||||
|
|
|
@ -170,14 +170,6 @@ static void pit_common_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
ISADevice *isadev = ISA_DEVICE(dev);
|
ISADevice *isadev = ISA_DEVICE(dev);
|
||||||
PITCommonState *pit = PIT_COMMON(dev);
|
PITCommonState *pit = PIT_COMMON(dev);
|
||||||
PITCommonClass *c = PIT_COMMON_GET_CLASS(pit);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = c->init(pit);
|
|
||||||
if (ret < 0) {
|
|
||||||
error_setg(errp, "PIT init failed.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isa_register_ioport(isadev, &pit->ioports, pit->iobase);
|
isa_register_ioport(isadev, &pit->ioports, pit->iobase);
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,6 @@ typedef struct PITCommonState {
|
||||||
typedef struct PITCommonClass {
|
typedef struct PITCommonClass {
|
||||||
ISADeviceClass parent_class;
|
ISADeviceClass parent_class;
|
||||||
|
|
||||||
int (*init)(PITCommonState *s);
|
|
||||||
void (*set_channel_gate)(PITCommonState *s, PITChannelState *sc, int val);
|
void (*set_channel_gate)(PITCommonState *s, PITChannelState *sc, int val);
|
||||||
void (*get_channel_info)(PITCommonState *s, PITChannelState *sc,
|
void (*get_channel_info)(PITCommonState *s, PITChannelState *sc,
|
||||||
PITChannelInfo *info);
|
PITChannelInfo *info);
|
||||||
|
|
Loading…
Reference in New Issue