xref: /kvm-unit-tests/lib/s390x/css.h (revision be704aff683c54fc108deaafacc7cb89ad0648d9)
1 /*
2  * CSS definitions
3  *
4  * Copyright IBM, Corp. 2020
5  * Author: Pierre Morel <pmorel@linux.ibm.com>
6  *
7  * This code is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2.
9  */
10 
11 #ifndef CSS_H
12 #define CSS_H
13 
14 #define lowcore_ptr ((struct lowcore *)0x0)
15 
16 /* subchannel ID bit 16 must always be one */
17 #define SCHID_ONE	0x00010000
18 
19 #define CCW_F_CD	0x80
20 #define CCW_F_CC	0x40
21 #define CCW_F_SLI	0x20
22 #define CCW_F_SKP	0x10
23 #define CCW_F_PCI	0x08
24 #define CCW_F_IDA	0x04
25 #define CCW_F_S		0x02
26 #define CCW_F_MIDA	0x01
27 
28 #define CCW_C_NOP	0x03
29 #define CCW_C_TIC	0x08
30 
31 struct ccw1 {
32 	uint8_t code;
33 	uint8_t flags;
34 	uint16_t count;
35 	uint32_t data_address;
36 } __attribute__ ((aligned(8)));
37 
38 #define ORB_CTRL_KEY	0xf0000000
39 #define ORB_CTRL_SPND	0x08000000
40 #define ORB_CTRL_STR	0x04000000
41 #define ORB_CTRL_MOD	0x02000000
42 #define ORB_CTRL_SYNC	0x01000000
43 #define ORB_CTRL_FMT	0x00800000
44 #define ORB_CTRL_PFCH	0x00400000
45 #define ORB_CTRL_ISIC	0x00200000
46 #define ORB_CTRL_ALCC	0x00100000
47 #define ORB_CTRL_SSIC	0x00080000
48 #define ORB_CTRL_CPTC	0x00040000
49 #define ORB_CTRL_C64	0x00020000
50 #define ORB_CTRL_I2K	0x00010000
51 #define ORB_CTRL_LPM	0x0000ff00
52 #define ORB_CTRL_ILS	0x00000080
53 #define ORB_CTRL_MIDAW	0x00000040
54 #define ORB_CTRL_ORBX	0x00000001
55 
56 #define ORB_LPM_DFLT	0x00008000
57 
58 struct orb {
59 	uint32_t intparm;
60 	uint32_t ctrl;
61 	uint32_t cpa;
62 	uint32_t prio;
63 	uint32_t reserved[4];
64 } __attribute__ ((aligned(4)));
65 
66 struct scsw {
67 #define SCSW_SC_PENDING		0x00000001
68 #define SCSW_SC_SECONDARY	0x00000002
69 #define SCSW_SC_PRIMARY		0x00000004
70 #define SCSW_SC_INTERMEDIATE	0x00000008
71 #define SCSW_SC_ALERT		0x00000010
72 	uint32_t ctrl;
73 	uint32_t ccw_addr;
74 #define SCSW_DEVS_DEV_END	0x04
75 #define SCSW_DEVS_SCH_END	0x08
76 	uint8_t  dev_stat;
77 #define SCSW_SCHS_PCI	0x80
78 #define SCSW_SCHS_IL	0x40
79 	uint8_t  sch_stat;
80 	uint16_t count;
81 };
82 
83 struct pmcw {
84 	uint32_t intparm;
85 #define PMCW_DNV	0x0001
86 #define PMCW_ENABLE	0x0080
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 	uint32_t flags2;
100 };
101 #define PMCW_CHANNEL_TYPE(pmcw) (pmcw->flags2 >> 21)
102 
103 struct schib {
104 	struct pmcw pmcw;
105 	struct scsw scsw;
106 	uint8_t  md[12];
107 } __attribute__ ((aligned(4)));
108 
109 struct irb {
110 	struct scsw scsw;
111 	uint32_t esw[5];
112 	uint32_t ecw[8];
113 	uint32_t emw[8];
114 } __attribute__ ((aligned(4)));
115 
116 #define CCW_CMD_SENSE_ID	0xe4
117 #define CSS_SENSEID_COMMON_LEN	8
118 struct senseid {
119 	/* common part */
120 	uint8_t reserved;        /* always 0x'FF' */
121 	uint16_t cu_type;        /* control unit type */
122 	uint8_t cu_model;        /* control unit model */
123 	uint16_t dev_type;       /* device type */
124 	uint8_t dev_model;       /* device model */
125 	uint8_t unused;          /* padding byte */
126 	uint8_t padding[256 - 8]; /* Extended part */
127 } __attribute__ ((aligned(4))) __attribute__ ((packed));
128 
129 /* CSS low level access functions */
130 
131 static inline int ssch(unsigned long schid, struct orb *addr)
132 {
133 	register long long reg1 asm("1") = schid;
134 	int cc;
135 
136 	asm volatile(
137 		"	ssch	0(%2)\n"
138 		"	ipm	%0\n"
139 		"	srl	%0,28\n"
140 		: "=d" (cc)
141 		: "d" (reg1), "a" (addr), "m" (*addr)
142 		: "cc", "memory");
143 	return cc;
144 }
145 
146 static inline int stsch(unsigned long schid, struct schib *addr)
147 {
148 	register unsigned long reg1 asm ("1") = schid;
149 	int cc;
150 
151 	asm volatile(
152 		"	stsch	0(%3)\n"
153 		"	ipm	%0\n"
154 		"	srl	%0,28"
155 		: "=d" (cc), "=m" (*addr)
156 		: "d" (reg1), "a" (addr)
157 		: "cc");
158 	return cc;
159 }
160 
161 static inline int msch(unsigned long schid, struct schib *addr)
162 {
163 	register unsigned long reg1 asm ("1") = schid;
164 	int cc;
165 
166 	asm volatile(
167 		"	msch	0(%3)\n"
168 		"	ipm	%0\n"
169 		"	srl	%0,28"
170 		: "=d" (cc)
171 		: "d" (reg1), "m" (*addr), "a" (addr)
172 		: "cc");
173 	return cc;
174 }
175 
176 static inline int tsch(unsigned long schid, struct irb *addr)
177 {
178 	register unsigned long reg1 asm ("1") = schid;
179 	int cc;
180 
181 	asm volatile(
182 		"	tsch	0(%3)\n"
183 		"	ipm	%0\n"
184 		"	srl	%0,28"
185 		: "=d" (cc), "=m" (*addr)
186 		: "d" (reg1), "a" (addr)
187 		: "cc");
188 	return cc;
189 }
190 
191 static inline int hsch(unsigned long schid)
192 {
193 	register unsigned long reg1 asm("1") = schid;
194 	int cc;
195 
196 	asm volatile(
197 		"	hsch\n"
198 		"	ipm	%0\n"
199 		"	srl	%0,28"
200 		: "=d" (cc)
201 		: "d" (reg1)
202 		: "cc");
203 	return cc;
204 }
205 
206 static inline int xsch(unsigned long schid)
207 {
208 	register unsigned long reg1 asm("1") = schid;
209 	int cc;
210 
211 	asm volatile(
212 		"	xsch\n"
213 		"	ipm	%0\n"
214 		"	srl	%0,28"
215 		: "=d" (cc)
216 		: "d" (reg1)
217 		: "cc");
218 	return cc;
219 }
220 
221 static inline int csch(unsigned long schid)
222 {
223 	register unsigned long reg1 asm("1") = schid;
224 	int cc;
225 
226 	asm volatile(
227 		"	csch\n"
228 		"	ipm	%0\n"
229 		"	srl	%0,28"
230 		: "=d" (cc)
231 		: "d" (reg1)
232 		: "cc");
233 	return cc;
234 }
235 
236 static inline int rsch(unsigned long schid)
237 {
238 	register unsigned long reg1 asm("1") = schid;
239 	int cc;
240 
241 	asm volatile(
242 		"	rsch\n"
243 		"	ipm	%0\n"
244 		"	srl	%0,28"
245 		: "=d" (cc)
246 		: "d" (reg1)
247 		: "cc");
248 	return cc;
249 }
250 
251 static inline int rchp(unsigned long chpid)
252 {
253 	register unsigned long reg1 asm("1") = chpid;
254 	int cc;
255 
256 	asm volatile(
257 		"	rchp\n"
258 		"	ipm	%0\n"
259 		"	srl	%0,28"
260 		: "=d" (cc)
261 		: "d" (reg1)
262 		: "cc");
263 	return cc;
264 }
265 
266 /* Debug functions */
267 char *dump_pmcw_flags(uint16_t f);
268 char *dump_scsw_flags(uint32_t f);
269 
270 void dump_scsw(struct scsw *scsw);
271 void dump_irb(struct irb *irbp);
272 void dump_schib(struct schib *sch);
273 struct ccw1 *dump_ccw(struct ccw1 *cp);
274 void dump_irb(struct irb *irbp);
275 void dump_pmcw(struct pmcw *p);
276 void dump_orb(struct orb *op);
277 
278 int css_enumerate(void);
279 #define MAX_ENABLE_RETRIES      5
280 
281 #define IO_SCH_ISC      3
282 int css_enable(int schid, int isc);
283 
284 /* Library functions */
285 int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw);
286 int start_single_ccw(unsigned int sid, int code, void *data, int count,
287 		     unsigned char flags);
288 void css_irq_io(void);
289 int css_residual_count(unsigned int schid);
290 
291 void enable_io_isc(uint8_t isc);
292 int wait_and_check_io_completion(int schid);
293 
294 #endif
295