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