xref: /openbmc/linux/drivers/s390/cio/ioasm.h (revision 64c70b1c)
1 #ifndef S390_CIO_IOASM_H
2 #define S390_CIO_IOASM_H
3 
4 #include <asm/chpid.h>
5 #include "schid.h"
6 
7 /*
8  * TPI info structure
9  */
10 struct tpi_info {
11 	struct subchannel_id schid;
12 	__u32 intparm;		 /* interruption parameter */
13 	__u32 adapter_IO : 1;
14 	__u32 reserved2	 : 1;
15 	__u32 isc	 : 3;
16 	__u32 reserved3	 : 12;
17 	__u32 int_type	 : 3;
18 	__u32 reserved4	 : 12;
19 } __attribute__ ((packed));
20 
21 
22 /*
23  * Some S390 specific IO instructions as inline
24  */
25 
26 static inline int stsch(struct subchannel_id schid,
27 			    volatile struct schib *addr)
28 {
29 	register struct subchannel_id reg1 asm ("1") = schid;
30 	int ccode;
31 
32 	asm volatile(
33 		"	stsch	0(%2)\n"
34 		"	ipm	%0\n"
35 		"	srl	%0,28"
36 		: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
37 	return ccode;
38 }
39 
40 static inline int stsch_err(struct subchannel_id schid,
41 				volatile struct schib *addr)
42 {
43 	register struct subchannel_id reg1 asm ("1") = schid;
44 	int ccode = -EIO;
45 
46 	asm volatile(
47 		"	stsch	0(%2)\n"
48 		"0:	ipm	%0\n"
49 		"	srl	%0,28\n"
50 		"1:\n"
51 		EX_TABLE(0b,1b)
52 		: "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
53 	return ccode;
54 }
55 
56 static inline int msch(struct subchannel_id schid,
57 			   volatile struct schib *addr)
58 {
59 	register struct subchannel_id reg1 asm ("1") = schid;
60 	int ccode;
61 
62 	asm volatile(
63 		"	msch	0(%2)\n"
64 		"	ipm	%0\n"
65 		"	srl	%0,28"
66 		: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
67 	return ccode;
68 }
69 
70 static inline int msch_err(struct subchannel_id schid,
71 			       volatile struct schib *addr)
72 {
73 	register struct subchannel_id reg1 asm ("1") = schid;
74 	int ccode = -EIO;
75 
76 	asm volatile(
77 		"	msch	0(%2)\n"
78 		"0:	ipm	%0\n"
79 		"	srl	%0,28\n"
80 		"1:\n"
81 		EX_TABLE(0b,1b)
82 		: "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
83 	return ccode;
84 }
85 
86 static inline int tsch(struct subchannel_id schid,
87 			   volatile struct irb *addr)
88 {
89 	register struct subchannel_id reg1 asm ("1") = schid;
90 	int ccode;
91 
92 	asm volatile(
93 		"	tsch	0(%2)\n"
94 		"	ipm	%0\n"
95 		"	srl	%0,28"
96 		: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
97 	return ccode;
98 }
99 
100 static inline int tpi( volatile struct tpi_info *addr)
101 {
102 	int ccode;
103 
104 	asm volatile(
105 		"	tpi	0(%1)\n"
106 		"	ipm	%0\n"
107 		"	srl	%0,28"
108 		: "=d" (ccode) : "a" (addr), "m" (*addr) : "cc");
109 	return ccode;
110 }
111 
112 static inline int ssch(struct subchannel_id schid,
113 			   volatile struct orb *addr)
114 {
115 	register struct subchannel_id reg1 asm ("1") = schid;
116 	int ccode;
117 
118 	asm volatile(
119 		"	ssch	0(%2)\n"
120 		"	ipm	%0\n"
121 		"	srl	%0,28"
122 		: "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
123 	return ccode;
124 }
125 
126 static inline int rsch(struct subchannel_id schid)
127 {
128 	register struct subchannel_id reg1 asm ("1") = schid;
129 	int ccode;
130 
131 	asm volatile(
132 		"	rsch\n"
133 		"	ipm	%0\n"
134 		"	srl	%0,28"
135 		: "=d" (ccode) : "d" (reg1) : "cc");
136 	return ccode;
137 }
138 
139 static inline int csch(struct subchannel_id schid)
140 {
141 	register struct subchannel_id reg1 asm ("1") = schid;
142 	int ccode;
143 
144 	asm volatile(
145 		"	csch\n"
146 		"	ipm	%0\n"
147 		"	srl	%0,28"
148 		: "=d" (ccode) : "d" (reg1) : "cc");
149 	return ccode;
150 }
151 
152 static inline int hsch(struct subchannel_id schid)
153 {
154 	register struct subchannel_id reg1 asm ("1") = schid;
155 	int ccode;
156 
157 	asm volatile(
158 		"	hsch\n"
159 		"	ipm	%0\n"
160 		"	srl	%0,28"
161 		: "=d" (ccode) : "d" (reg1) : "cc");
162 	return ccode;
163 }
164 
165 static inline int xsch(struct subchannel_id schid)
166 {
167 	register struct subchannel_id reg1 asm ("1") = schid;
168 	int ccode;
169 
170 	asm volatile(
171 		"	.insn	rre,0xb2760000,%1,0\n"
172 		"	ipm	%0\n"
173 		"	srl	%0,28"
174 		: "=d" (ccode) : "d" (reg1) : "cc");
175 	return ccode;
176 }
177 
178 static inline int chsc(void *chsc_area)
179 {
180 	typedef struct { char _[4096]; } addr_type;
181 	int cc;
182 
183 	asm volatile(
184 		"	.insn	rre,0xb25f0000,%2,0\n"
185 		"	ipm	%0\n"
186 		"	srl	%0,28\n"
187 		: "=d" (cc), "=m" (*(addr_type *) chsc_area)
188 		: "d" (chsc_area), "m" (*(addr_type *) chsc_area)
189 		: "cc");
190 	return cc;
191 }
192 
193 static inline int rchp(struct chp_id chpid)
194 {
195 	register struct chp_id reg1 asm ("1") = chpid;
196 	int ccode;
197 
198 	asm volatile(
199 		"	lr	1,%1\n"
200 		"	rchp\n"
201 		"	ipm	%0\n"
202 		"	srl	%0,28"
203 		: "=d" (ccode) : "d" (reg1) : "cc");
204 	return ccode;
205 }
206 
207 #endif
208