xref: /kvm-unit-tests/lib/s390x/css.h (revision 2c96b77ec9d3b1fcec7525174e23a6240ee05949)
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 /* Debug functions */
270 char *dump_pmcw_flags(uint16_t f);
271 char *dump_scsw_flags(uint32_t f);
272 
273 void dump_scsw(struct scsw *scsw);
274 void dump_irb(struct irb *irbp);
275 void dump_schib(struct schib *sch);
276 struct ccw1 *dump_ccw(struct ccw1 *cp);
277 void dump_irb(struct irb *irbp);
278 void dump_pmcw(struct pmcw *p);
279 void dump_orb(struct orb *op);
280 
281 int css_enumerate(void);
282 #define MAX_ENABLE_RETRIES      5
283 
284 #define IO_SCH_ISC      3
285 int css_enable(int schid, int isc);
286 bool css_enabled(int schid);
287 
288 /* Library functions */
289 int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw);
290 struct ccw1 *ccw_alloc(int code, void *data, int count, unsigned char flags);
291 void css_irq_io(void);
292 int css_residual_count(unsigned int schid);
293 
294 void enable_io_isc(uint8_t isc);
295 int wait_and_check_io_completion(int schid);
296 
297 /*
298  * CHSC definitions
299  */
300 struct chsc_header {
301 	uint16_t len;
302 	uint16_t code;
303 };
304 
305 /* Store Channel Subsystem Characteristics */
306 struct chsc_scsc {
307 	struct chsc_header req;
308 	uint16_t req_fmt;
309 	uint8_t cssid;
310 	uint8_t reserved[9];
311 	struct chsc_header res;
312 	uint32_t res_fmt;
313 #define CSSC_EXTENDED_MEASUREMENT_BLOCK 48
314 	uint64_t general_char[255];
315 	uint64_t chsc_char[254];
316 };
317 
318 extern struct chsc_scsc *chsc_scsc;
319 #define CHSC_SCSC	0x0010
320 #define CHSC_SCSC_LEN	0x0010
321 
322 bool get_chsc_scsc(void);
323 
324 #define CSS_GENERAL_FEAT_BITLEN	(255 * 64)
325 #define CSS_CHSC_FEAT_BITLEN	(254 * 64)
326 
327 #define CHSC_SCSC	0x0010
328 #define CHSC_SCSC_LEN	0x0010
329 
330 #define CHSC_ERROR	0x0000
331 #define CHSC_RSP_OK	0x0001
332 #define CHSC_RSP_INVAL	0x0002
333 #define CHSC_RSP_REQERR	0x0003
334 #define CHSC_RSP_ENOCMD	0x0004
335 #define CHSC_RSP_NODATA	0x0005
336 #define CHSC_RSP_SUP31B	0x0006
337 #define CHSC_RSP_EFRMT	0x0007
338 #define CHSC_RSP_ECSSID	0x0008
339 #define CHSC_RSP_ERFRMT	0x0009
340 #define CHSC_RSP_ESSID	0x000A
341 #define CHSC_RSP_EBUSY	0x000B
342 #define CHSC_RSP_MAX	0x000B
343 
344 static inline int _chsc(void *p)
345 {
346 	int cc;
347 
348 	asm volatile(" .insn   rre,0xb25f0000,%2,0\n"
349 		     " ipm     %0\n"
350 		     " srl     %0,28\n"
351 		     : "=d" (cc), "=m" (p)
352 		     : "d" (p), "m" (p)
353 		     : "cc");
354 
355 	return cc;
356 }
357 
358 bool chsc(void *p, uint16_t code, uint16_t len);
359 
360 #include <bitops.h>
361 #define css_test_general_feature(bit) test_bit_inv(bit, chsc_scsc->general_char)
362 #define css_test_chsc_feature(bit) test_bit_inv(bit, chsc_scsc->chsc_char)
363 
364 #define SCHM_DCTM	1 /* activate Device Connection TiMe */
365 #define SCHM_MBU	2 /* activate Measurement Block Update */
366 
367 static inline void schm(void *mbo, unsigned int flags)
368 {
369 	register void *__gpr2 asm("2") = mbo;
370 	register long __gpr1 asm("1") = flags;
371 
372 	asm("schm" : : "d" (__gpr2), "d" (__gpr1));
373 }
374 
375 bool css_enable_mb(int sid, uint64_t mb, uint16_t mbi, uint16_t flg, bool fmt1);
376 bool css_disable_mb(int schid);
377 
378 struct measurement_block_format0 {
379 	uint16_t ssch_rsch_count;
380 	uint16_t sample_count;
381 	uint32_t device_connect_time;
382 	uint32_t function_pending_time;
383 	uint32_t device_disconnect_time;
384 	uint32_t cu_queuing_time;
385 	uint32_t device_active_only_time;
386 	uint32_t device_busy_time;
387 	uint32_t initial_cmd_resp_time;
388 };
389 
390 struct measurement_block_format1 {
391 	uint32_t ssch_rsch_count;
392 	uint32_t sample_count;
393 	uint32_t device_connect_time;
394 	uint32_t function_pending_time;
395 	uint32_t device_disconnect_time;
396 	uint32_t cu_queuing_time;
397 	uint32_t device_active_only_time;
398 	uint32_t device_busy_time;
399 	uint32_t initial_cmd_resp_time;
400 	uint32_t irq_delay_time;
401 	uint32_t irq_prio_delay_time;
402 };
403 
404 #endif
405