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