149204458SJason J. Herne /*
249204458SJason J. Herne * SCLP event type
349204458SJason J. Herne * Signal CPU - Trigger SCLP interrupt for system CPU configure or
449204458SJason J. Herne * de-configure
549204458SJason J. Herne *
649204458SJason J. Herne * Copyright IBM, Corp. 2013
749204458SJason J. Herne *
849204458SJason J. Herne * Authors:
949204458SJason J. Herne * Thang Pham <thang.pham@us.ibm.com>
1049204458SJason J. Herne *
1149204458SJason J. Herne * This work is licensed under the terms of the GNU GPL, version 2 or (at your
1249204458SJason J. Herne * option) any later version. See the COPYING file in the top-level directory.
1349204458SJason J. Herne *
1449204458SJason J. Herne */
150b8fa32fSMarkus Armbruster
169615495aSPeter Maydell #include "qemu/osdep.h"
1749204458SJason J. Herne #include "hw/s390x/sclp.h"
180b8fa32fSMarkus Armbruster #include "qemu/module.h"
1949204458SJason J. Herne #include "hw/s390x/event-facility.h"
2049204458SJason J. Herne #include "sysemu/cpus.h"
2149204458SJason J. Herne
2249204458SJason J. Herne typedef struct ConfigMgtData {
2349204458SJason J. Herne EventBufferHeader ebh;
2449204458SJason J. Herne uint8_t reserved;
2549204458SJason J. Herne uint8_t event_qualifier;
2649204458SJason J. Herne } QEMU_PACKED ConfigMgtData;
2749204458SJason J. Herne
2849204458SJason J. Herne #define EVENT_QUAL_CPU_CHANGE 1
2949204458SJason J. Herne
raise_irq_cpu_hotplug(void)3049204458SJason J. Herne void raise_irq_cpu_hotplug(void)
3149204458SJason J. Herne {
32073f57aeSDavid Hildenbrand Object *obj = object_resolve_path_type("", TYPE_SCLP_CPU_HOTPLUG, NULL);
33073f57aeSDavid Hildenbrand
34073f57aeSDavid Hildenbrand SCLP_EVENT(obj)->event_pending = true;
35073f57aeSDavid Hildenbrand
36073f57aeSDavid Hildenbrand /* Trigger SCLP read operation */
37073f57aeSDavid Hildenbrand sclp_service_interrupt(0);
3849204458SJason J. Herne }
3949204458SJason J. Herne
send_mask(void)401ffed98fSClaudio Imbrenda static sccb_mask_t send_mask(void)
4149204458SJason J. Herne {
4249204458SJason J. Herne return SCLP_EVENT_MASK_CONFIG_MGT_DATA;
4349204458SJason J. Herne }
4449204458SJason J. Herne
receive_mask(void)451ffed98fSClaudio Imbrenda static sccb_mask_t receive_mask(void)
4649204458SJason J. Herne {
4749204458SJason J. Herne return 0;
4849204458SJason J. Herne }
4949204458SJason J. Herne
read_event_data(SCLPEvent * event,EventBufferHeader * evt_buf_hdr,int * slen)5049204458SJason J. Herne static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
5149204458SJason J. Herne int *slen)
5249204458SJason J. Herne {
5349204458SJason J. Herne ConfigMgtData *cdata = (ConfigMgtData *) evt_buf_hdr;
5449204458SJason J. Herne if (*slen < sizeof(ConfigMgtData)) {
5549204458SJason J. Herne return 0;
5649204458SJason J. Herne }
5749204458SJason J. Herne
5849204458SJason J. Herne /* Event is no longer pending */
5949204458SJason J. Herne if (!event->event_pending) {
6049204458SJason J. Herne return 0;
6149204458SJason J. Herne }
6249204458SJason J. Herne event->event_pending = false;
6349204458SJason J. Herne
6449204458SJason J. Herne /* Event header data */
6549204458SJason J. Herne cdata->ebh.length = cpu_to_be16(sizeof(ConfigMgtData));
6649204458SJason J. Herne cdata->ebh.type = SCLP_EVENT_CONFIG_MGT_DATA;
6749204458SJason J. Herne cdata->ebh.flags |= SCLP_EVENT_BUFFER_ACCEPTED;
6849204458SJason J. Herne
6949204458SJason J. Herne /* Trigger a rescan of CPUs by setting event qualifier */
7049204458SJason J. Herne cdata->event_qualifier = EVENT_QUAL_CPU_CHANGE;
7149204458SJason J. Herne *slen -= sizeof(ConfigMgtData);
7249204458SJason J. Herne
7349204458SJason J. Herne return 1;
7449204458SJason J. Herne }
7549204458SJason J. Herne
sclp_cpu_class_init(ObjectClass * oc,void * data)76*83f1ab12SPhilippe Mathieu-Daudé static void sclp_cpu_class_init(ObjectClass *oc, void *data)
7749204458SJason J. Herne {
7849204458SJason J. Herne SCLPEventClass *k = SCLP_EVENT_CLASS(oc);
79183f6b8dSCornelia Huck DeviceClass *dc = DEVICE_CLASS(oc);
8049204458SJason J. Herne
8149204458SJason J. Herne k->get_send_mask = send_mask;
8249204458SJason J. Herne k->get_receive_mask = receive_mask;
8349204458SJason J. Herne k->read_event_data = read_event_data;
84183f6b8dSCornelia Huck set_bit(DEVICE_CATEGORY_MISC, dc->categories);
857aa4d85dSCornelia Huck /*
867aa4d85dSCornelia Huck * Reason: raise_irq_cpu_hotplug() depends on an unique
877aa4d85dSCornelia Huck * TYPE_SCLP_CPU_HOTPLUG device, which is already created
887aa4d85dSCornelia Huck * by the sclp event facility
897aa4d85dSCornelia Huck */
907aa4d85dSCornelia Huck dc->user_creatable = false;
9149204458SJason J. Herne }
9249204458SJason J. Herne
9349204458SJason J. Herne static const TypeInfo sclp_cpu_info = {
9435925a7aSDavid Hildenbrand .name = TYPE_SCLP_CPU_HOTPLUG,
9549204458SJason J. Herne .parent = TYPE_SCLP_EVENT,
9649204458SJason J. Herne .instance_size = sizeof(SCLPEvent),
97*83f1ab12SPhilippe Mathieu-Daudé .class_init = sclp_cpu_class_init,
9849204458SJason J. Herne .class_size = sizeof(SCLPEventClass),
9949204458SJason J. Herne };
10049204458SJason J. Herne
sclp_cpu_register_types(void)10149204458SJason J. Herne static void sclp_cpu_register_types(void)
10249204458SJason J. Herne {
10349204458SJason J. Herne type_register_static(&sclp_cpu_info);
10449204458SJason J. Herne }
10549204458SJason J. Herne
10649204458SJason J. Herne type_init(sclp_cpu_register_types)
107