Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef S390_CIO_IOASM_H |
| 2 | #define S390_CIO_IOASM_H |
| 3 | |
Peter Oberparleiter | e5854a5 | 2007-04-27 16:01:31 +0200 | [diff] [blame] | 4 | #include <asm/chpid.h> |
Cornelia Huck | 9d92a7e | 2008-07-14 09:59:05 +0200 | [diff] [blame] | 5 | #include <asm/schid.h> |
Peter Oberparleiter | 2ab59de | 2015-12-18 12:59:32 +0100 | [diff] [blame] | 6 | #include <asm/crw.h> |
Sebastian Ott | dbda8ce | 2011-03-15 17:08:24 +0100 | [diff] [blame] | 7 | #include "orb.h" |
| 8 | #include "cio.h" |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 9 | #include "trace.h" |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame] | 10 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 11 | /* |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 12 | * Some S390 specific IO instructions as inline |
| 13 | */ |
| 14 | |
Peter Oberparleiter | 62e65da | 2015-12-18 12:58:47 +0100 | [diff] [blame] | 15 | static inline int stsch(struct subchannel_id schid, struct schib *addr) |
Cornelia Huck | fb6958a | 2006-01-06 00:19:25 -0800 | [diff] [blame] | 16 | { |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 17 | register struct subchannel_id reg1 asm ("1") = schid; |
| 18 | int ccode = -EIO; |
Cornelia Huck | fb6958a | 2006-01-06 00:19:25 -0800 | [diff] [blame] | 19 | |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 20 | asm volatile( |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 21 | " stsch 0(%3)\n" |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 22 | "0: ipm %0\n" |
| 23 | " srl %0,28\n" |
Cornelia Huck | fb6958a | 2006-01-06 00:19:25 -0800 | [diff] [blame] | 24 | "1:\n" |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 25 | EX_TABLE(0b,1b) |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 26 | : "+d" (ccode), "=m" (*addr) |
| 27 | : "d" (reg1), "a" (addr) |
| 28 | : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 29 | trace_s390_cio_stsch(schid, addr, ccode); |
| 30 | |
Cornelia Huck | fb6958a | 2006-01-06 00:19:25 -0800 | [diff] [blame] | 31 | return ccode; |
| 32 | } |
| 33 | |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 34 | static inline int msch(struct subchannel_id schid, struct schib *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 35 | { |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 36 | register struct subchannel_id reg1 asm ("1") = schid; |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 37 | int ccode = -EIO; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 38 | |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 39 | asm volatile( |
| 40 | " msch 0(%2)\n" |
| 41 | "0: ipm %0\n" |
| 42 | " srl %0,28\n" |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 43 | "1:\n" |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 44 | EX_TABLE(0b,1b) |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 45 | : "+d" (ccode) |
| 46 | : "d" (reg1), "a" (addr), "m" (*addr) |
| 47 | : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 48 | trace_s390_cio_msch(schid, addr, ccode); |
| 49 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 50 | return ccode; |
| 51 | } |
| 52 | |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 53 | static inline int tsch(struct subchannel_id schid, struct irb *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 54 | { |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 55 | register struct subchannel_id reg1 asm ("1") = schid; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 56 | int ccode; |
| 57 | |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 58 | asm volatile( |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 59 | " tsch 0(%3)\n" |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 60 | " ipm %0\n" |
| 61 | " srl %0,28" |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 62 | : "=d" (ccode), "=m" (*addr) |
| 63 | : "d" (reg1), "a" (addr) |
| 64 | : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 65 | trace_s390_cio_tsch(schid, addr, ccode); |
| 66 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | return ccode; |
| 68 | } |
| 69 | |
Sebastian Ott | dbda8ce | 2011-03-15 17:08:24 +0100 | [diff] [blame] | 70 | static inline int ssch(struct subchannel_id schid, union orb *addr) |
| 71 | { |
| 72 | register struct subchannel_id reg1 asm("1") = schid; |
| 73 | int ccode = -EIO; |
| 74 | |
| 75 | asm volatile( |
| 76 | " ssch 0(%2)\n" |
| 77 | "0: ipm %0\n" |
| 78 | " srl %0,28\n" |
| 79 | "1:\n" |
| 80 | EX_TABLE(0b, 1b) |
| 81 | : "+d" (ccode) |
| 82 | : "d" (reg1), "a" (addr), "m" (*addr) |
| 83 | : "cc", "memory"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 84 | trace_s390_cio_ssch(schid, addr, ccode); |
| 85 | |
Sebastian Ott | dbda8ce | 2011-03-15 17:08:24 +0100 | [diff] [blame] | 86 | return ccode; |
| 87 | } |
| 88 | |
| 89 | static inline int csch(struct subchannel_id schid) |
| 90 | { |
| 91 | register struct subchannel_id reg1 asm("1") = schid; |
| 92 | int ccode; |
| 93 | |
| 94 | asm volatile( |
| 95 | " csch\n" |
| 96 | " ipm %0\n" |
| 97 | " srl %0,28" |
| 98 | : "=d" (ccode) |
| 99 | : "d" (reg1) |
| 100 | : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 101 | trace_s390_cio_csch(schid, ccode); |
| 102 | |
Sebastian Ott | dbda8ce | 2011-03-15 17:08:24 +0100 | [diff] [blame] | 103 | return ccode; |
| 104 | } |
| 105 | |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 106 | static inline int tpi(struct tpi_info *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 107 | { |
| 108 | int ccode; |
| 109 | |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 110 | asm volatile( |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 111 | " tpi 0(%2)\n" |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 112 | " ipm %0\n" |
| 113 | " srl %0,28" |
Peter Oberparleiter | f9c9fe3 | 2008-10-10 21:33:15 +0200 | [diff] [blame] | 114 | : "=d" (ccode), "=m" (*addr) |
| 115 | : "a" (addr) |
| 116 | : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 117 | trace_s390_cio_tpi(addr, ccode); |
| 118 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 119 | return ccode; |
| 120 | } |
| 121 | |
Cornelia Huck | 4c24da7 | 2005-09-03 15:58:01 -0700 | [diff] [blame] | 122 | static inline int chsc(void *chsc_area) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 123 | { |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame] | 124 | typedef struct { char _[4096]; } addr_type; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 125 | int cc; |
| 126 | |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 127 | asm volatile( |
| 128 | " .insn rre,0xb25f0000,%2,0\n" |
| 129 | " ipm %0\n" |
| 130 | " srl %0,28\n" |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame] | 131 | : "=d" (cc), "=m" (*(addr_type *) chsc_area) |
| 132 | : "d" (chsc_area), "m" (*(addr_type *) chsc_area) |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 133 | : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 134 | trace_s390_cio_chsc(chsc_area, cc); |
| 135 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 136 | return cc; |
| 137 | } |
| 138 | |
Peter Oberparleiter | f86635f | 2007-04-27 16:01:26 +0200 | [diff] [blame] | 139 | static inline int rchp(struct chp_id chpid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 140 | { |
Peter Oberparleiter | f86635f | 2007-04-27 16:01:26 +0200 | [diff] [blame] | 141 | register struct chp_id reg1 asm ("1") = chpid; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 142 | int ccode; |
| 143 | |
Martin Schwidefsky | 94c12cc | 2006-09-28 16:56:43 +0200 | [diff] [blame] | 144 | asm volatile( |
| 145 | " lr 1,%1\n" |
| 146 | " rchp\n" |
| 147 | " ipm %0\n" |
| 148 | " srl %0,28" |
| 149 | : "=d" (ccode) : "d" (reg1) : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 150 | trace_s390_cio_rchp(chpid, ccode); |
| 151 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 152 | return ccode; |
| 153 | } |
| 154 | |
Peter Oberparleiter | 2ab59de | 2015-12-18 12:59:32 +0100 | [diff] [blame] | 155 | static inline int rsch(struct subchannel_id schid) |
| 156 | { |
| 157 | register struct subchannel_id reg1 asm("1") = schid; |
| 158 | int ccode; |
| 159 | |
| 160 | asm volatile( |
| 161 | " rsch\n" |
| 162 | " ipm %0\n" |
| 163 | " srl %0,28" |
| 164 | : "=d" (ccode) |
| 165 | : "d" (reg1) |
| 166 | : "cc", "memory"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 167 | trace_s390_cio_rsch(schid, ccode); |
| 168 | |
Peter Oberparleiter | 2ab59de | 2015-12-18 12:59:32 +0100 | [diff] [blame] | 169 | return ccode; |
| 170 | } |
| 171 | |
| 172 | static inline int hsch(struct subchannel_id schid) |
| 173 | { |
| 174 | register struct subchannel_id reg1 asm("1") = schid; |
| 175 | int ccode; |
| 176 | |
| 177 | asm volatile( |
| 178 | " hsch\n" |
| 179 | " ipm %0\n" |
| 180 | " srl %0,28" |
| 181 | : "=d" (ccode) |
| 182 | : "d" (reg1) |
| 183 | : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 184 | trace_s390_cio_hsch(schid, ccode); |
| 185 | |
Peter Oberparleiter | 2ab59de | 2015-12-18 12:59:32 +0100 | [diff] [blame] | 186 | return ccode; |
| 187 | } |
| 188 | |
| 189 | static inline int xsch(struct subchannel_id schid) |
| 190 | { |
| 191 | register struct subchannel_id reg1 asm("1") = schid; |
| 192 | int ccode; |
| 193 | |
| 194 | asm volatile( |
| 195 | " xsch\n" |
| 196 | " ipm %0\n" |
| 197 | " srl %0,28" |
| 198 | : "=d" (ccode) |
| 199 | : "d" (reg1) |
| 200 | : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 201 | trace_s390_cio_xsch(schid, ccode); |
| 202 | |
Peter Oberparleiter | 2ab59de | 2015-12-18 12:59:32 +0100 | [diff] [blame] | 203 | return ccode; |
| 204 | } |
| 205 | |
| 206 | static inline int stcrw(struct crw *crw) |
| 207 | { |
| 208 | int ccode; |
| 209 | |
| 210 | asm volatile( |
| 211 | " stcrw 0(%2)\n" |
| 212 | " ipm %0\n" |
| 213 | " srl %0,28\n" |
| 214 | : "=d" (ccode), "=m" (*crw) |
| 215 | : "a" (crw) |
| 216 | : "cc"); |
Peter Oberparleiter | 4224897 | 2015-12-18 12:59:36 +0100 | [diff] [blame^] | 217 | trace_s390_cio_stcrw(crw, ccode); |
| 218 | |
Peter Oberparleiter | 2ab59de | 2015-12-18 12:59:32 +0100 | [diff] [blame] | 219 | return ccode; |
| 220 | } |
| 221 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 222 | #endif |