1 /*
2  * SCLP
3  *    Event Facility definitions
4  *
5  * Copyright IBM, Corp. 2012
6  *
7  * Authors:
8  *  Heinz Graalfs <graalfs@de.ibm.com>
9  *
10  * This work is licensed under the terms of the GNU GPL, version 2 or (at your
11  * option) any later version.  See the COPYING file in the top-level directory.
12  *
13  */
14 
15 #ifndef HW_S390_SCLP_EVENT_FACILITY_H
16 #define HW_S390_SCLP_EVENT_FACILITY_H
17 
18 #include "qemu/thread.h"
19 #include "hw/qdev-core.h"
20 #include "hw/s390x/sclp.h"
21 #include "qom/object.h"
22 
23 /* SCLP event types */
24 #define SCLP_EVENT_OPRTNS_COMMAND               0x01
25 #define SCLP_EVENT_MESSAGE                      0x02
26 #define SCLP_EVENT_CONFIG_MGT_DATA              0x04
27 #define SCLP_EVENT_PMSGCMD                      0x09
28 #define SCLP_EVENT_ASCII_CONSOLE_DATA           0x1a
29 #define SCLP_EVENT_SIGNAL_QUIESCE               0x1d
30 
31 /* SCLP event masks */
32 #define SCLP_EVMASK(T)  (1ULL << (sizeof(sccb_mask_t) * 8 - (T)))
33 
34 #define SCLP_EVENT_MASK_OP_CMD          SCLP_EVMASK(SCLP_EVENT_OPRTNS_COMMAND)
35 #define SCLP_EVENT_MASK_MSG             SCLP_EVMASK(SCLP_EVENT_MESSAGE)
36 #define SCLP_EVENT_MASK_CONFIG_MGT_DATA SCLP_EVMASK(SCLP_EVENT_CONFIG_MGT_DATA)
37 #define SCLP_EVENT_MASK_PMSGCMD         SCLP_EVMASK(SCLP_EVENT_PMSGCMD)
38 #define SCLP_EVENT_MASK_MSG_ASCII       SCLP_EVMASK(SCLP_EVENT_ASCII_CONSOLE_DATA)
39 #define SCLP_EVENT_MASK_SIGNAL_QUIESCE  SCLP_EVMASK(SCLP_EVENT_SIGNAL_QUIESCE)
40 
41 #define SCLP_UNCONDITIONAL_READ                 0x00
42 #define SCLP_SELECTIVE_READ                     0x01
43 
44 #define TYPE_SCLP_EVENT "s390-sclp-event-type"
45 OBJECT_DECLARE_TYPE(SCLPEvent, SCLPEventClass,
46                     SCLP_EVENT)
47 
48 #define TYPE_SCLP_CPU_HOTPLUG "sclp-cpu-hotplug"
49 #define TYPE_SCLP_QUIESCE "sclpquiesce"
50 
51 #define SCLP_EVENT_MASK_LEN_MAX 1021
52 
53 typedef struct WriteEventMask {
54     SCCBHeader h;
55     uint16_t _reserved;
56     uint16_t mask_length;
57     uint8_t masks[];
58 /*
59  * Layout of the masks is
60  *  uint8_t cp_receive_mask[mask_length];
61  *  uint8_t cp_send_mask[mask_length];
62  *  uint8_t receive_mask[mask_length];
63  *  uint8_t send_mask[mask_length];
64  * where 1 <= mask_length <= SCLP_EVENT_MASK_LEN_MAX
65  */
66 } QEMU_PACKED WriteEventMask;
67 
68 #define WEM_CP_RECEIVE_MASK(wem, mask_len) ((wem)->masks)
69 #define WEM_CP_SEND_MASK(wem, mask_len) ((wem)->masks + (mask_len))
70 #define WEM_RECEIVE_MASK(wem, mask_len) ((wem)->masks + 2 * (mask_len))
71 #define WEM_SEND_MASK(wem, mask_len) ((wem)->masks + 3 * (mask_len))
72 
73 typedef uint64_t sccb_mask_t;
74 
75 typedef struct EventBufferHeader {
76     uint16_t length;
77     uint8_t  type;
78     uint8_t  flags;
79     uint16_t _reserved;
80 } QEMU_PACKED EventBufferHeader;
81 
82 typedef struct MdbHeader {
83     uint16_t length;
84     uint16_t type;
85     uint32_t tag;
86     uint32_t revision_code;
87 } QEMU_PACKED MdbHeader;
88 
89 typedef struct MTO {
90     uint16_t line_type_flags;
91     uint8_t  alarm_control;
92     uint8_t  _reserved[3];
93     char     message[];
94 } QEMU_PACKED MTO;
95 
96 typedef struct GO {
97     uint32_t domid;
98     uint8_t  hhmmss_time[8];
99     uint8_t  th_time[3];
100     uint8_t  _reserved_0;
101     uint8_t  dddyyyy_date[7];
102     uint8_t  _reserved_1;
103     uint16_t general_msg_flags;
104     uint8_t  _reserved_2[10];
105     uint8_t  originating_system_name[8];
106     uint8_t  job_guest_name[8];
107 } QEMU_PACKED GO;
108 
109 #define MESSAGE_TEXT 0x0004
110 
111 typedef struct MDBO {
112     uint16_t length;
113     uint16_t type;
114     union {
115         GO go;
116         MTO mto;
117     };
118 } QEMU_PACKED MDBO;
119 
120 typedef struct MDB {
121     MdbHeader header;
122     MDBO mdbo[];
123 } QEMU_PACKED MDB;
124 
125 typedef struct SclpMsg {
126     EventBufferHeader header;
127     MDB mdb;
128 } QEMU_PACKED SclpMsg;
129 
130 #define GDS_ID_MDSMU                            0x1310
131 #define GDS_ID_CPMSU                            0x1212
132 #define GDS_ID_TEXTCMD                          0x1320
133 
134 typedef struct GdsVector {
135     uint16_t length;
136     uint16_t gds_id;
137 } QEMU_PACKED GdsVector;
138 
139 #define GDS_KEY_SELFDEFTEXTMSG                  0x31
140 #define GDS_KEY_TEXTMSG                         0x30
141 
142 typedef struct GdsSubvector {
143     uint8_t length;
144     uint8_t key;
145 } QEMU_PACKED GdsSubvector;
146 
147 /* MDS Message Unit */
148 typedef struct MDMSU {
149     GdsVector mdmsu;
150     GdsVector cpmsu;
151     GdsVector text_command;
152     GdsSubvector self_def_text_message;
153     GdsSubvector text_message;
154 } QEMU_PACKED MDMSU;
155 
156 typedef struct WriteEventData {
157     SCCBHeader h;
158     EventBufferHeader ebh;
159 } QEMU_PACKED WriteEventData;
160 
161 typedef struct ReadEventData {
162     SCCBHeader h;
163     union {
164         sccb_mask_t mask;
165         EventBufferHeader ebh;
166     };
167 } QEMU_PACKED ReadEventData;
168 
169 struct SCLPEvent {
170     DeviceState qdev;
171     bool event_pending;
172     char *name;
173 };
174 
175 struct SCLPEventClass {
176     DeviceClass parent_class;
177     int (*init)(SCLPEvent *event);
178 
179     /* get SCLP's send mask */
180     sccb_mask_t (*get_send_mask)(void);
181 
182     /* get SCLP's receive mask */
183     sccb_mask_t (*get_receive_mask)(void);
184 
185     int (*read_event_data)(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
186                            int *slen);
187 
188     int (*write_event_data)(SCLPEvent *event, EventBufferHeader *evt_buf_hdr);
189 
190     /* can we handle this event type? */
191     bool (*can_handle_event)(uint8_t type);
192 };
193 
194 #define TYPE_SCLP_EVENT_FACILITY "s390-sclp-event-facility"
195 typedef struct SCLPEventFacility SCLPEventFacility;
196 typedef struct SCLPEventFacilityClass SCLPEventFacilityClass;
197 DECLARE_OBJ_CHECKERS(SCLPEventFacility, SCLPEventFacilityClass,
198                      EVENT_FACILITY, TYPE_SCLP_EVENT_FACILITY)
199 
200 struct SCLPEventFacilityClass {
201     SysBusDeviceClass parent_class;
202     void (*command_handler)(SCLPEventFacility *ef, SCCB *sccb, uint64_t code);
203     bool (*event_pending)(SCLPEventFacility *ef);
204 };
205 
206 BusState *sclp_get_event_facility_bus(void);
207 
208 #endif
209