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