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