xref: /kvm-unit-tests/lib/s390x/css.h (revision 6afb94812d924a754e2d44f6c5de9e1859b2df28)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * CSS definitions
4  *
5  * Copyright IBM Corp. 2020
6  * Author: Pierre Morel <pmorel@linux.ibm.com>
7  */
8 
9 #ifndef _S390X_CSS_H_
10 #define _S390X_CSS_H_
11 
12 /* subchannel ID bit 16 must always be one */
13 #define SCHID_ONE	0x00010000
14 
15 #define CCW_F_CD	0x80
16 #define CCW_F_CC	0x40
17 #define CCW_F_SLI	0x20
18 #define CCW_F_SKP	0x10
19 #define CCW_F_PCI	0x08
20 #define CCW_F_IDA	0x04
21 #define CCW_F_S		0x02
22 #define CCW_F_MIDA	0x01
23 
24 #define CCW_C_NOP	0x03
25 #define CCW_C_TIC	0x08
26 
27 struct ccw1 {
28 	uint8_t code;
29 	uint8_t flags;
30 	uint16_t count;
31 	uint32_t data_address;
32 } __attribute__ ((aligned(8)));
33 
34 #define ORB_CTRL_KEY	0xf0000000
35 #define ORB_CTRL_SPND	0x08000000
36 #define ORB_CTRL_STR	0x04000000
37 #define ORB_CTRL_MOD	0x02000000
38 #define ORB_CTRL_SYNC	0x01000000
39 #define ORB_CTRL_FMT	0x00800000
40 #define ORB_CTRL_PFCH	0x00400000
41 #define ORB_CTRL_ISIC	0x00200000
42 #define ORB_CTRL_ALCC	0x00100000
43 #define ORB_CTRL_SSIC	0x00080000
44 #define ORB_CTRL_CPTC	0x00040000
45 #define ORB_CTRL_C64	0x00020000
46 #define ORB_CTRL_I2K	0x00010000
47 #define ORB_CTRL_LPM	0x0000ff00
48 #define ORB_CTRL_ILS	0x00000080
49 #define ORB_CTRL_MIDAW	0x00000040
50 #define ORB_CTRL_ORBX	0x00000001
51 
52 #define ORB_LPM_DFLT	0x00008000
53 
54 struct orb {
55 	uint32_t intparm;
56 	uint32_t ctrl;
57 	uint32_t cpa;
58 	uint32_t prio;
59 	uint32_t reserved[4];
60 } __attribute__ ((aligned(4)));
61 
62 struct scsw {
63 #define SCSW_SC_PENDING		0x00000001
64 #define SCSW_SC_SECONDARY	0x00000002
65 #define SCSW_SC_PRIMARY		0x00000004
66 #define SCSW_SC_INTERMEDIATE	0x00000008
67 #define SCSW_SC_ALERT		0x00000010
68 	uint32_t ctrl;
69 	uint32_t ccw_addr;
70 #define SCSW_DEVS_DEV_END	0x04
71 #define SCSW_DEVS_SCH_END	0x08
72 	uint8_t  dev_stat;
73 #define SCSW_SCHS_PCI	0x80
74 #define SCSW_SCHS_IL	0x40
75 	uint8_t  sch_stat;
76 	uint16_t count;
77 };
78 
79 struct pmcw {
80 	uint32_t intparm;
81 #define PMCW_DNV	0x0001
82 #define PMCW_ENABLE	0x0080
83 #define PMCW_MBUE	0x0010
84 #define PMCW_DCTME	0x0008
85 #define PMCW_ISC_MASK	0x3800
86 #define PMCW_ISC_SHIFT	11
87 	uint16_t flags;
88 	uint16_t devnum;
89 	uint8_t  lpm;
90 	uint8_t  pnom;
91 	uint8_t  lpum;
92 	uint8_t  pim;
93 	uint16_t mbi;
94 	uint8_t  pom;
95 	uint8_t  pam;
96 	uint8_t  chpid[8];
97 #define PMCW_MBF1	0x0004
98 	uint32_t flags2;
99 };
100 #define PMCW_CHANNEL_TYPE(pmcw) (pmcw->flags2 >> 21)
101 
102 struct schib {
103 	struct pmcw pmcw;
104 	struct scsw scsw;
105 	uint64_t mbo;
106 	uint8_t  md[4];
107 } __attribute__ ((aligned(4)));
108 extern struct schib schib;
109 
110 struct irb {
111 	struct scsw scsw;
112 	uint32_t esw[5];
113 	uint32_t ecw[8];
114 	uint32_t emw[8];
115 } __attribute__ ((aligned(4)));
116 
117 #define CCW_CMD_SENSE_ID	0xe4
118 #define CSS_SENSEID_COMMON_LEN	8
119 struct senseid {
120 	/* common part */
121 	uint8_t reserved;        /* always 0x'FF' */
122 	uint16_t cu_type;        /* control unit type */
123 	uint8_t cu_model;        /* control unit model */
124 	uint16_t dev_type;       /* device type */
125 	uint8_t dev_model;       /* device model */
126 	uint8_t unused;          /* padding byte */
127 	uint8_t padding[256 - 8]; /* Extended part */
128 } __attribute__ ((aligned(4))) __attribute__ ((packed));
129 
130 /* CSS low level access functions */
131 
132 static inline int ssch(unsigned long schid, struct orb *addr)
133 {
134 	register long long reg1 asm("1") = schid;
135 	int cc;
136 
137 	asm volatile(
138 		"	ssch	0(%2)\n"
139 		"	ipm	%0\n"
140 		"	srl	%0,28\n"
141 		: "=d" (cc)
142 		: "d" (reg1), "a" (addr), "m" (*addr)
143 		: "cc", "memory");
144 	return cc;
145 }
146 
147 static inline int stsch(unsigned long schid, struct schib *addr)
148 {
149 	register unsigned long reg1 asm ("1") = schid;
150 	int cc;
151 
152 	asm volatile(
153 		"	stsch	0(%3)\n"
154 		"	ipm	%0\n"
155 		"	srl	%0,28"
156 		: "=d" (cc), "=m" (*addr)
157 		: "d" (reg1), "a" (addr)
158 		: "cc");
159 	return cc;
160 }
161 
162 static inline int msch(unsigned long schid, struct schib *addr)
163 {
164 	register unsigned long reg1 asm ("1") = schid;
165 	int cc;
166 
167 	asm volatile(
168 		"	msch	0(%3)\n"
169 		"	ipm	%0\n"
170 		"	srl	%0,28"
171 		: "=d" (cc)
172 		: "d" (reg1), "m" (*addr), "a" (addr)
173 		: "cc");
174 	return cc;
175 }
176 
177 static inline int tsch(unsigned long schid, struct irb *addr)
178 {
179 	register unsigned long reg1 asm ("1") = schid;
180 	int cc;
181 
182 	asm volatile(
183 		"	tsch	0(%3)\n"
184 		"	ipm	%0\n"
185 		"	srl	%0,28"
186 		: "=d" (cc), "=m" (*addr)
187 		: "d" (reg1), "a" (addr)
188 		: "cc");
189 	return cc;
190 }
191 
192 static inline int hsch(unsigned long schid)
193 {
194 	register unsigned long reg1 asm("1") = schid;
195 	int cc;
196 
197 	asm volatile(
198 		"	hsch\n"
199 		"	ipm	%0\n"
200 		"	srl	%0,28"
201 		: "=d" (cc)
202 		: "d" (reg1)
203 		: "cc");
204 	return cc;
205 }
206 
207 static inline int xsch(unsigned long schid)
208 {
209 	register unsigned long reg1 asm("1") = schid;
210 	int cc;
211 
212 	asm volatile(
213 		"	xsch\n"
214 		"	ipm	%0\n"
215 		"	srl	%0,28"
216 		: "=d" (cc)
217 		: "d" (reg1)
218 		: "cc");
219 	return cc;
220 }
221 
222 static inline int csch(unsigned long schid)
223 {
224 	register unsigned long reg1 asm("1") = schid;
225 	int cc;
226 
227 	asm volatile(
228 		"	csch\n"
229 		"	ipm	%0\n"
230 		"	srl	%0,28"
231 		: "=d" (cc)
232 		: "d" (reg1)
233 		: "cc");
234 	return cc;
235 }
236 
237 static inline int rsch(unsigned long schid)
238 {
239 	register unsigned long reg1 asm("1") = schid;
240 	int cc;
241 
242 	asm volatile(
243 		"	rsch\n"
244 		"	ipm	%0\n"
245 		"	srl	%0,28"
246 		: "=d" (cc)
247 		: "d" (reg1)
248 		: "cc");
249 	return cc;
250 }
251 
252 static inline int rchp(unsigned long chpid)
253 {
254 	register unsigned long reg1 asm("1") = chpid;
255 	int cc;
256 
257 	asm volatile(
258 		"	rchp\n"
259 		"	ipm	%0\n"
260 		"	srl	%0,28"
261 		: "=d" (cc)
262 		: "d" (reg1)
263 		: "cc");
264 	return cc;
265 }
266 
267 static inline int stcrw(uint32_t *crw)
268 {
269 	int cc;
270 
271 	asm volatile(
272 		"	stcrw	%[crw]\n"
273 		"	ipm	%[cc]\n"
274 		"	srl	%[cc],28"
275 		: [cc] "=d" (cc)
276 		: [crw] "Q" (*crw)
277 		: "cc", "memory");
278 	return cc;
279 }
280 
281 /* Debug functions */
282 char *dump_pmcw_flags(uint16_t f);
283 char *dump_scsw_flags(uint32_t f);
284 
285 void dump_scsw(struct scsw *scsw);
286 void dump_irb(struct irb *irbp);
287 void dump_schib(struct schib *sch);
288 struct ccw1 *dump_ccw(struct ccw1 *cp);
289 void dump_irb(struct irb *irbp);
290 void dump_pmcw(struct pmcw *p);
291 void dump_orb(struct orb *op);
292 
293 int css_enumerate(void);
294 #define MAX_ENABLE_RETRIES      5
295 
296 #define IO_SCH_ISC      3
297 int css_enable(int schid, int isc);
298 bool css_enabled(int schid);
299 
300 /* Library functions */
301 int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw);
302 struct ccw1 *ccw_alloc(int code, void *data, int count, unsigned char flags);
303 void css_irq_io(void);
304 int css_residual_count(unsigned int schid);
305 
306 void enable_io_isc(uint8_t isc);
307 int wait_and_check_io_completion(int schid);
308 
309 int css_find_installed_chpid(int sid, uint8_t *chpid_out);
310 int css_generate_crw(int sid);
311 
312 /*
313  * CHSC definitions
314  */
315 struct chsc_header {
316 	uint16_t len;
317 	uint16_t code;
318 };
319 
320 /* Store Channel Subsystem Characteristics */
321 struct chsc_scsc {
322 	struct chsc_header req;
323 	uint16_t req_fmt;
324 	uint8_t cssid;
325 	uint8_t reserved[9];
326 	struct chsc_header res;
327 	uint32_t res_fmt;
328 #define CSSC_EXTENDED_MEASUREMENT_BLOCK 48
329 	uint64_t general_char[255];
330 	uint64_t chsc_char[254];
331 };
332 
333 extern struct chsc_scsc *chsc_scsc;
334 #define CHSC_SCSC	0x0010
335 #define CHSC_SCSC_LEN	0x0010
336 
337 bool get_chsc_scsc(void);
338 
339 #define CSS_GENERAL_FEAT_BITLEN	(255 * 64)
340 #define CSS_CHSC_FEAT_BITLEN	(254 * 64)
341 
342 #define CHSC_SCSC	0x0010
343 #define CHSC_SCSC_LEN	0x0010
344 
345 #define CHSC_ERROR	0x0000
346 #define CHSC_RSP_OK	0x0001
347 #define CHSC_RSP_INVAL	0x0002
348 #define CHSC_RSP_REQERR	0x0003
349 #define CHSC_RSP_ENOCMD	0x0004
350 #define CHSC_RSP_NODATA	0x0005
351 #define CHSC_RSP_SUP31B	0x0006
352 #define CHSC_RSP_EFRMT	0x0007
353 #define CHSC_RSP_ECSSID	0x0008
354 #define CHSC_RSP_ERFRMT	0x0009
355 #define CHSC_RSP_ESSID	0x000A
356 #define CHSC_RSP_EBUSY	0x000B
357 #define CHSC_RSP_MAX	0x000B
358 
359 static inline int _chsc(void *p)
360 {
361 	int cc;
362 
363 	asm volatile(" .insn   rre,0xb25f0000,%2,0\n"
364 		     " ipm     %0\n"
365 		     " srl     %0,28\n"
366 		     : "=d" (cc), "=m" (p)
367 		     : "d" (p), "m" (p)
368 		     : "cc");
369 
370 	return cc;
371 }
372 
373 bool chsc(void *p, uint16_t code, uint16_t len);
374 
375 #include <bitops.h>
376 #define css_test_general_feature(bit) test_bit_inv(bit, chsc_scsc->general_char)
377 #define css_test_chsc_feature(bit) test_bit_inv(bit, chsc_scsc->chsc_char)
378 
379 #define SCHM_DCTM	1 /* activate Device Connection TiMe */
380 #define SCHM_MBU	2 /* activate Measurement Block Update */
381 
382 static inline void schm(void *mbo, unsigned int flags)
383 {
384 	register void *__gpr2 asm("2") = mbo;
385 	register long __gpr1 asm("1") = flags;
386 
387 	asm("schm" : : "d" (__gpr2), "d" (__gpr1));
388 }
389 
390 bool css_enable_mb(int sid, uint64_t mb, uint16_t mbi, uint16_t flg, bool fmt1);
391 bool css_disable_mb(int schid);
392 
393 struct measurement_block_format0 {
394 	uint16_t ssch_rsch_count;
395 	uint16_t sample_count;
396 	uint32_t device_connect_time;
397 	uint32_t function_pending_time;
398 	uint32_t device_disconnect_time;
399 	uint32_t cu_queuing_time;
400 	uint32_t device_active_only_time;
401 	uint32_t device_busy_time;
402 	uint32_t initial_cmd_resp_time;
403 };
404 
405 struct measurement_block_format1 {
406 	uint32_t ssch_rsch_count;
407 	uint32_t sample_count;
408 	uint32_t device_connect_time;
409 	uint32_t function_pending_time;
410 	uint32_t device_disconnect_time;
411 	uint32_t cu_queuing_time;
412 	uint32_t device_active_only_time;
413 	uint32_t device_busy_time;
414 	uint32_t initial_cmd_resp_time;
415 	uint32_t irq_delay_time;
416 	uint32_t irq_prio_delay_time;
417 };
418 
419 #endif
420