diff options
-rw-r--r-- | hw/s390x/event-facility.c | 34 | ||||
-rw-r--r-- | hw/s390x/sclp.c | 58 | ||||
-rw-r--r-- | include/hw/s390x/event-facility.h | 19 | ||||
-rw-r--r-- | include/hw/s390x/sclp.h | 24 |
4 files changed, 47 insertions, 88 deletions
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index e0ee7379e2..8ad2dc4094 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -26,8 +26,8 @@ typedef struct SCLPEventsBus { } SCLPEventsBus; struct SCLPEventFacility { + SysBusDevice parent_obj; SCLPEventsBus sbus; - DeviceState *qdev; /* guest' receive mask */ unsigned int receive_mask; }; @@ -315,21 +315,15 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code) } } -static int init_event_facility(S390SCLPDevice *sdev) +static int init_event_facility(SCLPEventFacility *event_facility) { - SCLPEventFacility *event_facility; + DeviceState *sdev = DEVICE(event_facility); DeviceState *quiesce; - event_facility = g_malloc0(sizeof(SCLPEventFacility)); - sdev->ef = event_facility; - sdev->sclp_command_handler = command_handler; - sdev->event_pending = event_pending; - - /* Spawn a new sclp-events facility */ + /* Spawn a new bus for SCLP events */ qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus), - TYPE_SCLP_EVENTS_BUS, DEVICE(sdev), NULL); + TYPE_SCLP_EVENTS_BUS, sdev, NULL); event_facility->sbus.qbus.allow_hotplug = 0; - event_facility->qdev = (DeviceState *) sdev; quiesce = qdev_create(&event_facility->sbus.qbus, "sclpquiesce"); if (!quiesce) { @@ -346,25 +340,29 @@ static int init_event_facility(S390SCLPDevice *sdev) static void reset_event_facility(DeviceState *dev) { - S390SCLPDevice *sdev = SCLP_S390_DEVICE(dev); + SCLPEventFacility *sdev = EVENT_FACILITY(dev); - sdev->ef->receive_mask = 0; + sdev->receive_mask = 0; } static void init_event_facility_class(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - S390SCLPDeviceClass *k = SCLP_S390_DEVICE_CLASS(klass); + SysBusDeviceClass *sbdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(sbdc); + SCLPEventFacilityClass *k = EVENT_FACILITY_CLASS(dc); dc->reset = reset_event_facility; k->init = init_event_facility; + k->command_handler = command_handler; + k->event_pending = event_pending; } static const TypeInfo sclp_event_facility_info = { - .name = "s390-sclp-event-facility", - .parent = TYPE_DEVICE_S390_SCLP, - .instance_size = sizeof(S390SCLPDevice), + .name = TYPE_SCLP_EVENT_FACILITY, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(SCLPEventFacility), .class_init = init_event_facility_class, + .class_size = sizeof(SCLPEventFacilityClass), }; static int event_qdev_init(DeviceState *qdev) diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c index 98809777c8..d8ddf35e58 100644 --- a/hw/s390x/sclp.c +++ b/hw/s390x/sclp.c @@ -18,11 +18,12 @@ #include "sysemu/sysemu.h" #include "hw/s390x/sclp.h" +#include "hw/s390x/event-facility.h" -static inline S390SCLPDevice *get_event_facility(void) +static inline SCLPEventFacility *get_event_facility(void) { ObjectProperty *op = object_property_find(qdev_get_machine(), - "s390-sclp-event-facility", + TYPE_SCLP_EVENT_FACILITY, NULL); assert(op); return op->opaque; @@ -91,7 +92,8 @@ static void sclp_read_cpu_info(SCCB *sccb) static void sclp_execute(SCCB *sccb, uint32_t code) { - S390SCLPDevice *sdev = get_event_facility(); + SCLPEventFacility *ef = get_event_facility(); + SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef); switch (code & SCLP_CMD_CODE_MASK) { case SCLP_CMDW_READ_SCP_INFO: @@ -102,7 +104,7 @@ static void sclp_execute(SCCB *sccb, uint32_t code) sclp_read_cpu_info(sccb); break; default: - sdev->sclp_command_handler(sdev->ef, sccb, code); + efc->command_handler(ef, sccb, code); break; } } @@ -156,11 +158,13 @@ out: void sclp_service_interrupt(uint32_t sccb) { - S390SCLPDevice *sdev = get_event_facility(); + SCLPEventFacility *ef = get_event_facility(); + SCLPEventFacilityClass *efc = EVENT_FACILITY_GET_CLASS(ef); + uint32_t param = sccb & ~3; /* Indicate whether an event is still pending */ - param |= sdev->event_pending(sdev->ef) ? 1 : 0; + param |= efc->event_pending(ef) ? 1 : 0; if (!param) { /* No need to send an interrupt, there's nothing to be notified about */ @@ -173,47 +177,9 @@ void sclp_service_interrupt(uint32_t sccb) void s390_sclp_init(void) { - DeviceState *dev = qdev_create(NULL, "s390-sclp-event-facility"); + DeviceState *dev = qdev_create(NULL, TYPE_SCLP_EVENT_FACILITY); - object_property_add_child(qdev_get_machine(), "s390-sclp-event-facility", + object_property_add_child(qdev_get_machine(), TYPE_SCLP_EVENT_FACILITY, OBJECT(dev), NULL); qdev_init_nofail(dev); } - -static int s390_sclp_dev_init(SysBusDevice *dev) -{ - int r; - S390SCLPDevice *sdev = (S390SCLPDevice *)dev; - S390SCLPDeviceClass *sclp = SCLP_S390_DEVICE_GET_CLASS(dev); - - r = sclp->init(sdev); - if (!r) { - assert(sdev->event_pending); - assert(sdev->sclp_command_handler); - } - - return r; -} - -static void s390_sclp_device_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *dc = SYS_BUS_DEVICE_CLASS(klass); - - dc->init = s390_sclp_dev_init; -} - -static const TypeInfo s390_sclp_device_info = { - .name = TYPE_DEVICE_S390_SCLP, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(S390SCLPDevice), - .class_init = s390_sclp_device_class_init, - .class_size = sizeof(S390SCLPDeviceClass), - .abstract = true, -}; - -static void s390_sclp_register_types(void) -{ - type_register_static(&s390_sclp_device_info); -} - -type_init(s390_sclp_register_types) diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index 870edd46f6..6a062b668a 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -176,4 +176,23 @@ typedef struct SCLPEventClass { bool (*can_handle_event)(uint8_t type); } SCLPEventClass; +#define TYPE_SCLP_EVENT_FACILITY "s390-sclp-event-facility" +#define EVENT_FACILITY(obj) \ + OBJECT_CHECK(SCLPEventFacility, (obj), TYPE_SCLP_EVENT_FACILITY) +#define EVENT_FACILITY_CLASS(klass) \ + OBJECT_CLASS_CHECK(SCLPEventFacilityClass, (klass), \ + TYPE_SCLP_EVENT_FACILITY) +#define EVENT_FACILITY_GET_CLASS(obj) \ + OBJECT_GET_CLASS(SCLPEventFacilityClass, (obj), \ + TYPE_SCLP_EVENT_FACILITY) + +typedef struct SCLPEventFacility SCLPEventFacility; + +typedef struct SCLPEventFacilityClass { + DeviceClass parent_class; + int (*init)(SCLPEventFacility *ef); + void (*command_handler)(SCLPEventFacility *ef, SCCB *sccb, uint64_t code); + bool (*event_pending)(SCLPEventFacility *ef); +} SCLPEventFacilityClass; + #endif diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h index 35112d92b1..7ef16226df 100644 --- a/include/hw/s390x/sclp.h +++ b/include/hw/s390x/sclp.h @@ -161,30 +161,6 @@ static inline int sccb_data_len(SCCB *sccb) return be16_to_cpu(sccb->h.length) - sizeof(sccb->h); } -#define TYPE_DEVICE_S390_SCLP "s390-sclp-device" -#define SCLP_S390_DEVICE(obj) \ - OBJECT_CHECK(S390SCLPDevice, (obj), TYPE_DEVICE_S390_SCLP) -#define SCLP_S390_DEVICE_CLASS(klass) \ - OBJECT_CLASS_CHECK(S390SCLPDeviceClass, (klass), \ - TYPE_DEVICE_S390_SCLP) -#define SCLP_S390_DEVICE_GET_CLASS(obj) \ - OBJECT_GET_CLASS(S390SCLPDeviceClass, (obj), \ - TYPE_DEVICE_S390_SCLP) - -typedef struct SCLPEventFacility SCLPEventFacility; - -typedef struct S390SCLPDevice { - SysBusDevice busdev; - SCLPEventFacility *ef; - void (*sclp_command_handler)(SCLPEventFacility *ef, SCCB *sccb, - uint64_t code); - bool (*event_pending)(SCLPEventFacility *ef); -} S390SCLPDevice; - -typedef struct S390SCLPDeviceClass { - DeviceClass qdev; - int (*init)(S390SCLPDevice *sdev); -} S390SCLPDeviceClass; void s390_sclp_init(void); void sclp_service_interrupt(uint32_t sccb); |