xref: /openbmc/qemu/hw/s390x/event-facility.c (revision 9c4218e9)
1 /*
2  * SCLP
3  *    Event Facility
4  *       handles SCLP event types
5  *          - Signal Quiesce - system power down
6  *          - ASCII Console Data - VT220 read and write
7  *
8  * Copyright IBM, Corp. 2012
9  *
10  * Authors:
11  *  Heinz Graalfs <graalfs@de.ibm.com>
12  *
13  * This work is licensed under the terms of the GNU GPL, version 2 or (at your
14  * option) any later version.  See the COPYING file in the top-level directory.
15  *
16  */
17 
18 #include "qemu/osdep.h"
19 #include "sysemu/sysemu.h"
20 
21 #include "hw/s390x/sclp.h"
22 #include "hw/s390x/event-facility.h"
23 
24 typedef struct SCLPEventsBus {
25     BusState qbus;
26 } SCLPEventsBus;
27 
28 struct SCLPEventFacility {
29     SysBusDevice parent_obj;
30     SCLPEventsBus sbus;
31     /* guest' receive mask */
32     unsigned int receive_mask;
33 };
34 
35 /* return true if any child has event pending set */
36 static bool event_pending(SCLPEventFacility *ef)
37 {
38     BusChild *kid;
39     SCLPEvent *event;
40     SCLPEventClass *event_class;
41 
42     QTAILQ_FOREACH(kid, &ef->sbus.qbus.children, sibling) {
43         DeviceState *qdev = kid->child;
44         event = DO_UPCAST(SCLPEvent, qdev, qdev);
45         event_class = SCLP_EVENT_GET_CLASS(event);
46         if (event->event_pending &&
47             event_class->get_send_mask() & ef->receive_mask) {
48             return true;
49         }
50     }
51     return false;
52 }
53 
54 static unsigned int get_host_send_mask(SCLPEventFacility *ef)
55 {
56     unsigned int mask;
57     BusChild *kid;
58     SCLPEventClass *child;
59 
60     mask = 0;
61 
62     QTAILQ_FOREACH(kid, &ef->sbus.qbus.children, sibling) {
63         DeviceState *qdev = kid->child;
64         child = SCLP_EVENT_GET_CLASS((SCLPEvent *) qdev);
65         mask |= child->get_send_mask();
66     }
67     return mask;
68 }
69 
70 static unsigned int get_host_receive_mask(SCLPEventFacility *ef)
71 {
72     unsigned int mask;
73     BusChild *kid;
74     SCLPEventClass *child;
75 
76     mask = 0;
77 
78     QTAILQ_FOREACH(kid, &ef->sbus.qbus.children, sibling) {
79         DeviceState *qdev = kid->child;
80         child = SCLP_EVENT_GET_CLASS((SCLPEvent *) qdev);
81         mask |= child->get_receive_mask();
82     }
83     return mask;
84 }
85 
86 static uint16_t write_event_length_check(SCCB *sccb)
87 {
88     int slen;
89     unsigned elen = 0;
90     EventBufferHeader *event;
91     WriteEventData *wed = (WriteEventData *) sccb;
92 
93     event = (EventBufferHeader *) &wed->ebh;
94     for (slen = sccb_data_len(sccb); slen > 0; slen -= elen) {
95         elen = be16_to_cpu(event->length);
96         if (elen < sizeof(*event) || elen > slen) {
97             return SCLP_RC_EVENT_BUFFER_SYNTAX_ERROR;
98         }
99         event = (void *) event + elen;
100     }
101     if (slen) {
102         return SCLP_RC_INCONSISTENT_LENGTHS;
103     }
104     return SCLP_RC_NORMAL_COMPLETION;
105 }
106 
107 static uint16_t handle_write_event_buf(SCLPEventFacility *ef,
108                                        EventBufferHeader *event_buf, SCCB *sccb)
109 {
110     uint16_t rc;
111     BusChild *kid;
112     SCLPEvent *event;
113     SCLPEventClass *ec;
114 
115     rc = SCLP_RC_INVALID_FUNCTION;
116 
117     QTAILQ_FOREACH(kid, &ef->sbus.qbus.children, sibling) {
118         DeviceState *qdev = kid->child;
119         event = (SCLPEvent *) qdev;
120         ec = SCLP_EVENT_GET_CLASS(event);
121 
122         if (ec->write_event_data &&
123             ec->can_handle_event(event_buf->type)) {
124             rc = ec->write_event_data(event, event_buf);
125             break;
126         }
127     }
128     return rc;
129 }
130 
131 static uint16_t handle_sccb_write_events(SCLPEventFacility *ef, SCCB *sccb)
132 {
133     uint16_t rc;
134     int slen;
135     unsigned elen = 0;
136     EventBufferHeader *event_buf;
137     WriteEventData *wed = (WriteEventData *) sccb;
138 
139     event_buf = &wed->ebh;
140     rc = SCLP_RC_NORMAL_COMPLETION;
141 
142     /* loop over all contained event buffers */
143     for (slen = sccb_data_len(sccb); slen > 0; slen -= elen) {
144         elen = be16_to_cpu(event_buf->length);
145 
146         /* in case of a previous error mark all trailing buffers
147          * as not accepted */
148         if (rc != SCLP_RC_NORMAL_COMPLETION) {
149             event_buf->flags &= ~(SCLP_EVENT_BUFFER_ACCEPTED);
150         } else {
151             rc = handle_write_event_buf(ef, event_buf, sccb);
152         }
153         event_buf = (void *) event_buf + elen;
154     }
155     return rc;
156 }
157 
158 static void write_event_data(SCLPEventFacility *ef, SCCB *sccb)
159 {
160     if (sccb->h.function_code != SCLP_FC_NORMAL_WRITE) {
161         sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_FUNCTION);
162         goto out;
163     }
164     if (be16_to_cpu(sccb->h.length) < 8) {
165         sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
166         goto out;
167     }
168     /* first do a sanity check of the write events */
169     sccb->h.response_code = cpu_to_be16(write_event_length_check(sccb));
170 
171     /* if no early error, then execute */
172     if (sccb->h.response_code == be16_to_cpu(SCLP_RC_NORMAL_COMPLETION)) {
173         sccb->h.response_code =
174                 cpu_to_be16(handle_sccb_write_events(ef, sccb));
175     }
176 
177 out:
178     return;
179 }
180 
181 static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
182                                         unsigned int mask)
183 {
184     uint16_t rc;
185     int slen;
186     unsigned elen;
187     BusChild *kid;
188     SCLPEvent *event;
189     SCLPEventClass *ec;
190     EventBufferHeader *event_buf;
191     ReadEventData *red = (ReadEventData *) sccb;
192 
193     event_buf = &red->ebh;
194     event_buf->length = 0;
195     slen = sizeof(sccb->data);
196 
197     rc = SCLP_RC_NO_EVENT_BUFFERS_STORED;
198 
199     QTAILQ_FOREACH(kid, &ef->sbus.qbus.children, sibling) {
200         DeviceState *qdev = kid->child;
201         event = (SCLPEvent *) qdev;
202         ec = SCLP_EVENT_GET_CLASS(event);
203 
204         if (mask & ec->get_send_mask()) {
205             if (ec->read_event_data(event, event_buf, &slen)) {
206                 elen = be16_to_cpu(event_buf->length);
207                 event_buf = (EventBufferHeader *) ((char *)event_buf + elen);
208                 rc = SCLP_RC_NORMAL_COMPLETION;
209             }
210         }
211     }
212 
213     if (sccb->h.control_mask[2] & SCLP_VARIABLE_LENGTH_RESPONSE) {
214         /* architecture suggests to reset variable-length-response bit */
215         sccb->h.control_mask[2] &= ~SCLP_VARIABLE_LENGTH_RESPONSE;
216         /* with a new length value */
217         sccb->h.length = cpu_to_be16(SCCB_SIZE - slen);
218     }
219     return rc;
220 }
221 
222 static void read_event_data(SCLPEventFacility *ef, SCCB *sccb)
223 {
224     unsigned int sclp_active_selection_mask;
225     unsigned int sclp_cp_receive_mask;
226 
227     ReadEventData *red = (ReadEventData *) sccb;
228 
229     if (be16_to_cpu(sccb->h.length) != SCCB_SIZE) {
230         sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
231         goto out;
232     }
233 
234     sclp_cp_receive_mask = ef->receive_mask;
235 
236     /* get active selection mask */
237     switch (sccb->h.function_code) {
238     case SCLP_UNCONDITIONAL_READ:
239         sclp_active_selection_mask = sclp_cp_receive_mask;
240         break;
241     case SCLP_SELECTIVE_READ:
242         sclp_active_selection_mask = be32_to_cpu(red->mask);
243         if (!sclp_cp_receive_mask ||
244             (sclp_active_selection_mask & ~sclp_cp_receive_mask)) {
245             sccb->h.response_code =
246                     cpu_to_be16(SCLP_RC_INVALID_SELECTION_MASK);
247             goto out;
248         }
249         break;
250     default:
251         sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_FUNCTION);
252         goto out;
253     }
254     sccb->h.response_code = cpu_to_be16(
255             handle_sccb_read_events(ef, sccb, sclp_active_selection_mask));
256 
257 out:
258     return;
259 }
260 
261 static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
262 {
263     WriteEventMask *we_mask = (WriteEventMask *) sccb;
264 
265     /* Attention: We assume that Linux uses 4-byte masks, what it actually
266        does. Architecture allows for masks of variable size, though */
267     if (be16_to_cpu(we_mask->mask_length) != 4) {
268         sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_MASK_LENGTH);
269         goto out;
270     }
271 
272     /* keep track of the guest's capability masks */
273     ef->receive_mask = be32_to_cpu(we_mask->cp_receive_mask);
274 
275     /* return the SCLP's capability masks to the guest */
276     we_mask->send_mask = cpu_to_be32(get_host_send_mask(ef));
277     we_mask->receive_mask = cpu_to_be32(get_host_receive_mask(ef));
278 
279     sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
280 
281 out:
282     return;
283 }
284 
285 /* qemu object creation and initialization functions */
286 
287 #define TYPE_SCLP_EVENTS_BUS "s390-sclp-events-bus"
288 
289 static void sclp_events_bus_realize(BusState *bus, Error **errp)
290 {
291     BusChild *kid;
292 
293     /* TODO: recursive realization has to be done in common code */
294     QTAILQ_FOREACH(kid, &bus->children, sibling) {
295         DeviceState *dev = kid->child;
296 
297         object_property_set_bool(OBJECT(dev), true, "realized", errp);
298         if (*errp) {
299             return;
300         }
301     }
302 }
303 
304 static void sclp_events_bus_class_init(ObjectClass *klass, void *data)
305 {
306     BusClass *bc = BUS_CLASS(klass);
307 
308     bc->realize = sclp_events_bus_realize;
309 }
310 
311 static const TypeInfo sclp_events_bus_info = {
312     .name = TYPE_SCLP_EVENTS_BUS,
313     .parent = TYPE_BUS,
314     .class_init = sclp_events_bus_class_init,
315 };
316 
317 static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code)
318 {
319     switch (code & SCLP_CMD_CODE_MASK) {
320     case SCLP_CMD_READ_EVENT_DATA:
321         read_event_data(ef, sccb);
322         break;
323     case SCLP_CMD_WRITE_EVENT_DATA:
324         write_event_data(ef, sccb);
325         break;
326     case SCLP_CMD_WRITE_EVENT_MASK:
327         write_event_mask(ef, sccb);
328         break;
329     default:
330         sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
331         break;
332     }
333 }
334 
335 static const VMStateDescription vmstate_event_facility = {
336     .name = "vmstate-event-facility",
337     .version_id = 0,
338     .minimum_version_id = 0,
339     .fields = (VMStateField[]) {
340         VMSTATE_UINT32(receive_mask, SCLPEventFacility),
341         VMSTATE_END_OF_LIST()
342      }
343 };
344 
345 static void init_event_facility(Object *obj)
346 {
347     SCLPEventFacility *event_facility = EVENT_FACILITY(obj);
348     DeviceState *sdev = DEVICE(obj);
349     Object *new;
350 
351     /* Spawn a new bus for SCLP events */
352     qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
353                         TYPE_SCLP_EVENTS_BUS, sdev, NULL);
354 
355     new = object_new(TYPE_SCLP_QUIESCE);
356     object_property_add_child(obj, TYPE_SCLP_QUIESCE, new, NULL);
357     object_unref(new);
358     qdev_set_parent_bus(DEVICE(new), &event_facility->sbus.qbus);
359 
360     new = object_new(TYPE_SCLP_CPU_HOTPLUG);
361     object_property_add_child(obj, TYPE_SCLP_CPU_HOTPLUG, new, NULL);
362     object_unref(new);
363     qdev_set_parent_bus(DEVICE(new), &event_facility->sbus.qbus);
364     /* the facility will automatically realize the devices via the bus */
365 }
366 
367 static void reset_event_facility(DeviceState *dev)
368 {
369     SCLPEventFacility *sdev = EVENT_FACILITY(dev);
370 
371     sdev->receive_mask = 0;
372 }
373 
374 static void init_event_facility_class(ObjectClass *klass, void *data)
375 {
376     SysBusDeviceClass *sbdc = SYS_BUS_DEVICE_CLASS(klass);
377     DeviceClass *dc = DEVICE_CLASS(sbdc);
378     SCLPEventFacilityClass *k = EVENT_FACILITY_CLASS(dc);
379 
380     dc->reset = reset_event_facility;
381     dc->vmsd = &vmstate_event_facility;
382     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
383     k->command_handler = command_handler;
384     k->event_pending = event_pending;
385 }
386 
387 static const TypeInfo sclp_event_facility_info = {
388     .name          = TYPE_SCLP_EVENT_FACILITY,
389     .parent        = TYPE_SYS_BUS_DEVICE,
390     .instance_init = init_event_facility,
391     .instance_size = sizeof(SCLPEventFacility),
392     .class_init    = init_event_facility_class,
393     .class_size    = sizeof(SCLPEventFacilityClass),
394 };
395 
396 static void event_realize(DeviceState *qdev, Error **errp)
397 {
398     SCLPEvent *event = SCLP_EVENT(qdev);
399     SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event);
400 
401     if (child->init) {
402         int rc = child->init(event);
403         if (rc < 0) {
404             error_setg(errp, "SCLP event initialization failed.");
405             return;
406         }
407     }
408 }
409 
410 static void event_unrealize(DeviceState *qdev, Error **errp)
411 {
412     SCLPEvent *event = SCLP_EVENT(qdev);
413     SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event);
414     if (child->exit) {
415         int rc = child->exit(event);
416         if (rc < 0) {
417             error_setg(errp, "SCLP event exit failed.");
418             return;
419         }
420     }
421 }
422 
423 static void event_class_init(ObjectClass *klass, void *data)
424 {
425     DeviceClass *dc = DEVICE_CLASS(klass);
426 
427     dc->bus_type = TYPE_SCLP_EVENTS_BUS;
428     dc->realize = event_realize;
429     dc->unrealize = event_unrealize;
430 }
431 
432 static const TypeInfo sclp_event_type_info = {
433     .name = TYPE_SCLP_EVENT,
434     .parent = TYPE_DEVICE,
435     .instance_size = sizeof(SCLPEvent),
436     .class_init = event_class_init,
437     .class_size = sizeof(SCLPEventClass),
438     .abstract = true,
439 };
440 
441 static void register_types(void)
442 {
443     type_register_static(&sclp_events_bus_info);
444     type_register_static(&sclp_event_facility_info);
445     type_register_static(&sclp_event_type_info);
446 }
447 
448 type_init(register_types)
449