1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include "qemu/osdep.h"
16#include "sysemu/sysemu.h"
17#include "hw/s390x/sclp.h"
18#include "hw/s390x/event-facility.h"
19#include "cpu.h"
20#include "sysemu/cpus.h"
21#include "sysemu/kvm.h"
22
23typedef struct ConfigMgtData {
24 EventBufferHeader ebh;
25 uint8_t reserved;
26 uint8_t event_qualifier;
27} QEMU_PACKED ConfigMgtData;
28
29#define EVENT_QUAL_CPU_CHANGE 1
30
31void raise_irq_cpu_hotplug(void)
32{
33 Object *obj = object_resolve_path_type("", TYPE_SCLP_CPU_HOTPLUG, NULL);
34
35 SCLP_EVENT(obj)->event_pending = true;
36
37
38 sclp_service_interrupt(0);
39}
40
41static unsigned int send_mask(void)
42{
43 return SCLP_EVENT_MASK_CONFIG_MGT_DATA;
44}
45
46static unsigned int receive_mask(void)
47{
48 return 0;
49}
50
51static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
52 int *slen)
53{
54 ConfigMgtData *cdata = (ConfigMgtData *) evt_buf_hdr;
55 if (*slen < sizeof(ConfigMgtData)) {
56 return 0;
57 }
58
59
60 if (!event->event_pending) {
61 return 0;
62 }
63 event->event_pending = false;
64
65
66 cdata->ebh.length = cpu_to_be16(sizeof(ConfigMgtData));
67 cdata->ebh.type = SCLP_EVENT_CONFIG_MGT_DATA;
68 cdata->ebh.flags |= SCLP_EVENT_BUFFER_ACCEPTED;
69
70
71 cdata->event_qualifier = EVENT_QUAL_CPU_CHANGE;
72 *slen -= sizeof(ConfigMgtData);
73
74 return 1;
75}
76
77static void cpu_class_init(ObjectClass *oc, void *data)
78{
79 SCLPEventClass *k = SCLP_EVENT_CLASS(oc);
80 DeviceClass *dc = DEVICE_CLASS(oc);
81
82 k->get_send_mask = send_mask;
83 k->get_receive_mask = receive_mask;
84 k->read_event_data = read_event_data;
85 set_bit(DEVICE_CATEGORY_MISC, dc->categories);
86}
87
88static const TypeInfo sclp_cpu_info = {
89 .name = TYPE_SCLP_CPU_HOTPLUG,
90 .parent = TYPE_SCLP_EVENT,
91 .instance_size = sizeof(SCLPEvent),
92 .class_init = cpu_class_init,
93 .class_size = sizeof(SCLPEventClass),
94};
95
96static void sclp_cpu_register_types(void)
97{
98 type_register_static(&sclp_cpu_info);
99}
100
101type_init(sclp_cpu_register_types)
102