xref: /kvm-unit-tests/lib/s390x/css.h (revision 9cab58249f98adc451933530fd7e618e1856eb94)
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 
ssch(unsigned long schid,struct orb * addr)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 
stsch(unsigned long schid,struct schib * addr)147 static inline int stsch(unsigned long schid, struct schib *addr)
148 {
149 	register unsigned long reg1 asm ("1") = schid;
150 	uint64_t bogus_cc = 1;
151 	int cc;
152 
153 	asm volatile(
154 		"       tmll    %[bogus_cc],3\n"
155 		"	stsch	0(%3)\n"
156 		"	ipm	%0\n"
157 		"	srl	%0,28"
158 		: "=d" (cc), "=m" (*addr)
159 		: "d" (reg1), "a" (addr), [bogus_cc] "d" (bogus_cc)
160 		: "cc");
161 	return cc;
162 }
163 
msch(unsigned long schid,struct schib * addr)164 static inline int msch(unsigned long schid, struct schib *addr)
165 {
166 	register unsigned long reg1 asm ("1") = schid;
167 	int cc;
168 
169 	asm volatile(
170 		"	msch	0(%3)\n"
171 		"	ipm	%0\n"
172 		"	srl	%0,28"
173 		: "=d" (cc)
174 		: "d" (reg1), "m" (*addr), "a" (addr)
175 		: "cc");
176 	return cc;
177 }
178 
tsch(unsigned long schid,struct irb * addr)179 static inline int tsch(unsigned long schid, struct irb *addr)
180 {
181 	register unsigned long reg1 asm ("1") = schid;
182 	uint64_t bogus_cc = 2;
183 	int cc;
184 
185 	asm volatile(
186 		"       tmll    %[bogus_cc],3\n"
187 		"	tsch	0(%3)\n"
188 		"	ipm	%0\n"
189 		"	srl	%0,28"
190 		: "=d" (cc), "=m" (*addr)
191 		: "d" (reg1), "a" (addr), [bogus_cc] "d" (bogus_cc)
192 		: "cc");
193 	return cc;
194 }
195 
hsch(unsigned long schid)196 static inline int hsch(unsigned long schid)
197 {
198 	register unsigned long reg1 asm("1") = schid;
199 	int cc;
200 
201 	asm volatile(
202 		"	hsch\n"
203 		"	ipm	%0\n"
204 		"	srl	%0,28"
205 		: "=d" (cc)
206 		: "d" (reg1)
207 		: "cc");
208 	return cc;
209 }
210 
xsch(unsigned long schid)211 static inline int xsch(unsigned long schid)
212 {
213 	register unsigned long reg1 asm("1") = schid;
214 	int cc;
215 
216 	asm volatile(
217 		"	xsch\n"
218 		"	ipm	%0\n"
219 		"	srl	%0,28"
220 		: "=d" (cc)
221 		: "d" (reg1)
222 		: "cc");
223 	return cc;
224 }
225 
csch(unsigned long schid)226 static inline int csch(unsigned long schid)
227 {
228 	register unsigned long reg1 asm("1") = schid;
229 	int cc;
230 
231 	asm volatile(
232 		"	csch\n"
233 		"	ipm	%0\n"
234 		"	srl	%0,28"
235 		: "=d" (cc)
236 		: "d" (reg1)
237 		: "cc");
238 	return cc;
239 }
240 
rsch(unsigned long schid)241 static inline int rsch(unsigned long schid)
242 {
243 	register unsigned long reg1 asm("1") = schid;
244 	int cc;
245 
246 	asm volatile(
247 		"	rsch\n"
248 		"	ipm	%0\n"
249 		"	srl	%0,28"
250 		: "=d" (cc)
251 		: "d" (reg1)
252 		: "cc");
253 	return cc;
254 }
255 
rchp(unsigned long chpid)256 static inline int rchp(unsigned long chpid)
257 {
258 	register unsigned long reg1 asm("1") = chpid;
259 	uint64_t bogus_cc = 1;
260 	int cc;
261 
262 	asm volatile(
263 		"       tmll    %[bogus_cc],3\n"
264 		"	rchp\n"
265 		"	ipm	%0\n"
266 		"	srl	%0,28"
267 		: "=d" (cc)
268 		: "d" (reg1), [bogus_cc] "d" (bogus_cc)
269 		: "cc");
270 	return cc;
271 }
272 
stcrw(uint32_t * crw)273 static inline int stcrw(uint32_t *crw)
274 {
275 	uint64_t bogus_cc = 1;
276 	int cc;
277 
278 	asm volatile(
279 		"       tmll    %[bogus_cc],3\n"
280 		"	stcrw	%[crw]\n"
281 		"	ipm	%[cc]\n"
282 		"	srl	%[cc],28"
283 		: [cc] "=d" (cc)
284 		: [crw] "Q" (*crw), [bogus_cc] "d" (bogus_cc)
285 		: "cc", "memory");
286 	return cc;
287 }
288 
289 /* Debug functions */
290 char *dump_pmcw_flags(uint16_t f);
291 char *dump_scsw_flags(uint32_t f);
292 
293 void dump_scsw(struct scsw *scsw);
294 void dump_irb(struct irb *irbp);
295 void dump_schib(struct schib *sch);
296 struct ccw1 *dump_ccw(struct ccw1 *cp);
297 void dump_irb(struct irb *irbp);
298 void dump_pmcw(struct pmcw *p);
299 void dump_orb(struct orb *op);
300 
301 int css_enumerate(void);
302 #define MAX_ENABLE_RETRIES      5
303 
304 #define IO_SCH_ISC      3
305 int css_enable(int schid, int isc);
306 bool css_enabled(int schid);
307 
308 /* Library functions */
309 int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw);
310 struct ccw1 *ccw_alloc(int code, void *data, int count, unsigned char flags);
311 void css_irq_io(void);
312 int css_residual_count(unsigned int schid);
313 
314 void enable_io_isc(uint8_t isc);
315 int wait_and_check_io_completion(int schid);
316 
317 int css_find_installed_chpid(int sid, uint8_t *chpid_out);
318 int css_generate_crw(int sid);
319 
320 /*
321  * CHSC definitions
322  */
323 struct chsc_header {
324 	uint16_t len;
325 	uint16_t code;
326 };
327 
328 /* Store Channel Subsystem Characteristics */
329 struct chsc_scsc {
330 	struct chsc_header req;
331 	uint16_t req_fmt;
332 	uint8_t cssid;
333 	uint8_t reserved[9];
334 	struct chsc_header res;
335 	uint32_t res_fmt;
336 #define CSSC_EXTENDED_MEASUREMENT_BLOCK 48
337 	uint64_t general_char[255];
338 	uint64_t chsc_char[254];
339 };
340 
341 extern struct chsc_scsc *chsc_scsc;
342 #define CHSC_SCSC	0x0010
343 #define CHSC_SCSC_LEN	0x0010
344 
345 bool get_chsc_scsc(void);
346 
347 #define CSS_GENERAL_FEAT_BITLEN	(255 * 64)
348 #define CSS_CHSC_FEAT_BITLEN	(254 * 64)
349 
350 #define CHSC_SCSC	0x0010
351 #define CHSC_SCSC_LEN	0x0010
352 
353 #define CHSC_ERROR	0x0000
354 #define CHSC_RSP_OK	0x0001
355 #define CHSC_RSP_INVAL	0x0002
356 #define CHSC_RSP_REQERR	0x0003
357 #define CHSC_RSP_ENOCMD	0x0004
358 #define CHSC_RSP_NODATA	0x0005
359 #define CHSC_RSP_SUP31B	0x0006
360 #define CHSC_RSP_EFRMT	0x0007
361 #define CHSC_RSP_ECSSID	0x0008
362 #define CHSC_RSP_ERFRMT	0x0009
363 #define CHSC_RSP_ESSID	0x000A
364 #define CHSC_RSP_EBUSY	0x000B
365 #define CHSC_RSP_MAX	0x000B
366 
_chsc(void * p)367 static inline int _chsc(void *p)
368 {
369 	int cc;
370 
371 	asm volatile(" .insn   rre,0xb25f0000,%2,0\n"
372 		     " ipm     %0\n"
373 		     " srl     %0,28\n"
374 		     : "=d" (cc), "=m" (p)
375 		     : "d" (p), "m" (p)
376 		     : "cc");
377 
378 	return cc;
379 }
380 
381 bool chsc(void *p, uint16_t code, uint16_t len);
382 
383 #include <bitops.h>
384 #define css_test_general_feature(bit) test_bit_inv(bit, chsc_scsc->general_char)
385 #define css_test_chsc_feature(bit) test_bit_inv(bit, chsc_scsc->chsc_char)
386 
387 #define SCHM_DCTM	1 /* activate Device Connection TiMe */
388 #define SCHM_MBU	2 /* activate Measurement Block Update */
389 
schm(void * mbo,unsigned int flags)390 static inline void schm(void *mbo, unsigned int flags)
391 {
392 	register void *__gpr2 asm("2") = mbo;
393 	register long __gpr1 asm("1") = flags;
394 
395 	asm("schm" : : "d" (__gpr2), "d" (__gpr1));
396 }
397 
398 bool css_enable_mb(int sid, uint64_t mb, uint16_t mbi, uint16_t flg, bool fmt1);
399 bool css_disable_mb(int schid);
400 
401 struct measurement_block_format0 {
402 	uint16_t ssch_rsch_count;
403 	uint16_t sample_count;
404 	uint32_t device_connect_time;
405 	uint32_t function_pending_time;
406 	uint32_t device_disconnect_time;
407 	uint32_t cu_queuing_time;
408 	uint32_t device_active_only_time;
409 	uint32_t device_busy_time;
410 	uint32_t initial_cmd_resp_time;
411 };
412 
413 struct measurement_block_format1 {
414 	uint32_t ssch_rsch_count;
415 	uint32_t sample_count;
416 	uint32_t device_connect_time;
417 	uint32_t function_pending_time;
418 	uint32_t device_disconnect_time;
419 	uint32_t cu_queuing_time;
420 	uint32_t device_active_only_time;
421 	uint32_t device_busy_time;
422 	uint32_t initial_cmd_resp_time;
423 	uint32_t irq_delay_time;
424 	uint32_t irq_prio_delay_time;
425 };
426 
427 #endif
428