xref: /openbmc/linux/drivers/s390/cio/ioasm.h (revision 9ac8d3fb)
1 #ifndef S390_CIO_IOASM_H
2 #define S390_CIO_IOASM_H
3 
4 #include <asm/chpid.h>
5 #include <asm/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, struct schib *addr)
27 {
28 	register struct subchannel_id reg1 asm ("1") = schid;
29 	int ccode;
30 
31 	asm volatile(
32 		"	stsch	0(%3)\n"
33 		"	ipm	%0\n"
34 		"	srl	%0,28"
35 		: "=d" (ccode), "=m" (*addr)
36 		: "d" (reg1), "a" (addr)
37 		: "cc");
38 	return ccode;
39 }
40 
41 static inline int stsch_err(struct subchannel_id schid, struct schib *addr)
42 {
43 	register struct subchannel_id reg1 asm ("1") = schid;
44 	int ccode = -EIO;
45 
46 	asm volatile(
47 		"	stsch	0(%3)\n"
48 		"0:	ipm	%0\n"
49 		"	srl	%0,28\n"
50 		"1:\n"
51 		EX_TABLE(0b,1b)
52 		: "+d" (ccode), "=m" (*addr)
53 		: "d" (reg1), "a" (addr)
54 		: "cc");
55 	return ccode;
56 }
57 
58 static inline int msch(struct subchannel_id schid, struct schib *addr)
59 {
60 	register struct subchannel_id reg1 asm ("1") = schid;
61 	int ccode;
62 
63 	asm volatile(
64 		"	msch	0(%2)\n"
65 		"	ipm	%0\n"
66 		"	srl	%0,28"
67 		: "=d" (ccode)
68 		: "d" (reg1), "a" (addr), "m" (*addr)
69 		: "cc");
70 	return ccode;
71 }
72 
73 static inline int msch_err(struct subchannel_id schid, struct schib *addr)
74 {
75 	register struct subchannel_id reg1 asm ("1") = schid;
76 	int ccode = -EIO;
77 
78 	asm volatile(
79 		"	msch	0(%2)\n"
80 		"0:	ipm	%0\n"
81 		"	srl	%0,28\n"
82 		"1:\n"
83 		EX_TABLE(0b,1b)
84 		: "+d" (ccode)
85 		: "d" (reg1), "a" (addr), "m" (*addr)
86 		: "cc");
87 	return ccode;
88 }
89 
90 static inline int tsch(struct subchannel_id schid, struct irb *addr)
91 {
92 	register struct subchannel_id reg1 asm ("1") = schid;
93 	int ccode;
94 
95 	asm volatile(
96 		"	tsch	0(%3)\n"
97 		"	ipm	%0\n"
98 		"	srl	%0,28"
99 		: "=d" (ccode), "=m" (*addr)
100 		: "d" (reg1), "a" (addr)
101 		: "cc");
102 	return ccode;
103 }
104 
105 static inline int tpi(struct tpi_info *addr)
106 {
107 	int ccode;
108 
109 	asm volatile(
110 		"	tpi	0(%2)\n"
111 		"	ipm	%0\n"
112 		"	srl	%0,28"
113 		: "=d" (ccode), "=m" (*addr)
114 		: "a" (addr)
115 		: "cc");
116 	return ccode;
117 }
118 
119 static inline int chsc(void *chsc_area)
120 {
121 	typedef struct { char _[4096]; } addr_type;
122 	int cc;
123 
124 	asm volatile(
125 		"	.insn	rre,0xb25f0000,%2,0\n"
126 		"	ipm	%0\n"
127 		"	srl	%0,28\n"
128 		: "=d" (cc), "=m" (*(addr_type *) chsc_area)
129 		: "d" (chsc_area), "m" (*(addr_type *) chsc_area)
130 		: "cc");
131 	return cc;
132 }
133 
134 static inline int rchp(struct chp_id chpid)
135 {
136 	register struct chp_id reg1 asm ("1") = chpid;
137 	int ccode;
138 
139 	asm volatile(
140 		"	lr	1,%1\n"
141 		"	rchp\n"
142 		"	ipm	%0\n"
143 		"	srl	%0,28"
144 		: "=d" (ccode) : "d" (reg1) : "cc");
145 	return ccode;
146 }
147 
148 #endif
149