hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/s390/pci/pci_insn.c
....@@ -8,9 +8,11 @@
88 #include <linux/export.h>
99 #include <linux/errno.h>
1010 #include <linux/delay.h>
11
+#include <linux/jump_label.h>
1112 #include <asm/facility.h>
1213 #include <asm/pci_insn.h>
1314 #include <asm/pci_debug.h>
15
+#include <asm/pci_io.h>
1416 #include <asm/processor.h>
1517
1618 #define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */
....@@ -96,13 +98,15 @@
9698 }
9799
98100 /* Set Interruption Controls */
99
-int zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc)
101
+int __zpci_set_irq_ctrl(u16 ctl, u8 isc, union zpci_sic_iib *iib)
100102 {
101103 if (!test_facility(72))
102104 return -EIO;
103
- asm volatile (
104
- " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n"
105
- : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused));
105
+
106
+ asm volatile(
107
+ ".insn rsy,0xeb00000000d1,%[ctl],%[isc],%[iib]\n"
108
+ : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [iib] "Q" (*iib));
109
+
106110 return 0;
107111 }
108112
....@@ -140,7 +144,7 @@
140144 return cc;
141145 }
142146
143
-int zpci_load(u64 *data, u64 req, u64 offset)
147
+int __zpci_load(u64 *data, u64 req, u64 offset)
144148 {
145149 u8 status;
146150 int cc;
....@@ -153,6 +157,52 @@
153157
154158 if (cc)
155159 zpci_err_insn(cc, status, req, offset);
160
+
161
+ return (cc > 0) ? -EIO : cc;
162
+}
163
+EXPORT_SYMBOL_GPL(__zpci_load);
164
+
165
+static inline int zpci_load_fh(u64 *data, const volatile void __iomem *addr,
166
+ unsigned long len)
167
+{
168
+ struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(addr)];
169
+ u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, len);
170
+
171
+ return __zpci_load(data, req, ZPCI_OFFSET(addr));
172
+}
173
+
174
+static inline int __pcilg_mio(u64 *data, u64 ioaddr, u64 len, u8 *status)
175
+{
176
+ register u64 addr asm("2") = ioaddr;
177
+ register u64 r3 asm("3") = len;
178
+ int cc = -ENXIO;
179
+ u64 __data;
180
+
181
+ asm volatile (
182
+ " .insn rre,0xb9d60000,%[data],%[ioaddr]\n"
183
+ "0: ipm %[cc]\n"
184
+ " srl %[cc],28\n"
185
+ "1:\n"
186
+ EX_TABLE(0b, 1b)
187
+ : [cc] "+d" (cc), [data] "=d" (__data), "+d" (r3)
188
+ : [ioaddr] "d" (addr)
189
+ : "cc");
190
+ *status = r3 >> 24 & 0xff;
191
+ *data = __data;
192
+ return cc;
193
+}
194
+
195
+int zpci_load(u64 *data, const volatile void __iomem *addr, unsigned long len)
196
+{
197
+ u8 status;
198
+ int cc;
199
+
200
+ if (!static_branch_unlikely(&have_mio))
201
+ return zpci_load_fh(data, addr, len);
202
+
203
+ cc = __pcilg_mio(data, (__force u64) addr, len, &status);
204
+ if (cc)
205
+ zpci_err_insn(cc, status, 0, (__force u64) addr);
156206
157207 return (cc > 0) ? -EIO : cc;
158208 }
....@@ -178,7 +228,7 @@
178228 return cc;
179229 }
180230
181
-int zpci_store(u64 data, u64 req, u64 offset)
231
+int __zpci_store(u64 data, u64 req, u64 offset)
182232 {
183233 u8 status;
184234 int cc;
....@@ -191,6 +241,50 @@
191241
192242 if (cc)
193243 zpci_err_insn(cc, status, req, offset);
244
+
245
+ return (cc > 0) ? -EIO : cc;
246
+}
247
+EXPORT_SYMBOL_GPL(__zpci_store);
248
+
249
+static inline int zpci_store_fh(const volatile void __iomem *addr, u64 data,
250
+ unsigned long len)
251
+{
252
+ struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(addr)];
253
+ u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, len);
254
+
255
+ return __zpci_store(data, req, ZPCI_OFFSET(addr));
256
+}
257
+
258
+static inline int __pcistg_mio(u64 data, u64 ioaddr, u64 len, u8 *status)
259
+{
260
+ register u64 addr asm("2") = ioaddr;
261
+ register u64 r3 asm("3") = len;
262
+ int cc = -ENXIO;
263
+
264
+ asm volatile (
265
+ " .insn rre,0xb9d40000,%[data],%[ioaddr]\n"
266
+ "0: ipm %[cc]\n"
267
+ " srl %[cc],28\n"
268
+ "1:\n"
269
+ EX_TABLE(0b, 1b)
270
+ : [cc] "+d" (cc), "+d" (r3)
271
+ : [data] "d" (data), [ioaddr] "d" (addr)
272
+ : "cc");
273
+ *status = r3 >> 24 & 0xff;
274
+ return cc;
275
+}
276
+
277
+int zpci_store(const volatile void __iomem *addr, u64 data, unsigned long len)
278
+{
279
+ u8 status;
280
+ int cc;
281
+
282
+ if (!static_branch_unlikely(&have_mio))
283
+ return zpci_store_fh(addr, data, len);
284
+
285
+ cc = __pcistg_mio(data, (__force u64) addr, len, &status);
286
+ if (cc)
287
+ zpci_err_insn(cc, status, 0, (__force u64) addr);
194288
195289 return (cc > 0) ? -EIO : cc;
196290 }
....@@ -214,7 +308,7 @@
214308 return cc;
215309 }
216310
217
-int zpci_store_block(const u64 *data, u64 req, u64 offset)
311
+int __zpci_store_block(const u64 *data, u64 req, u64 offset)
218312 {
219313 u8 status;
220314 int cc;
....@@ -230,4 +324,63 @@
230324
231325 return (cc > 0) ? -EIO : cc;
232326 }
233
-EXPORT_SYMBOL_GPL(zpci_store_block);
327
+EXPORT_SYMBOL_GPL(__zpci_store_block);
328
+
329
+static inline int zpci_write_block_fh(volatile void __iomem *dst,
330
+ const void *src, unsigned long len)
331
+{
332
+ struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(dst)];
333
+ u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, len);
334
+ u64 offset = ZPCI_OFFSET(dst);
335
+
336
+ return __zpci_store_block(src, req, offset);
337
+}
338
+
339
+static inline int __pcistb_mio(const u64 *data, u64 ioaddr, u64 len, u8 *status)
340
+{
341
+ int cc = -ENXIO;
342
+
343
+ asm volatile (
344
+ " .insn rsy,0xeb00000000d4,%[len],%[ioaddr],%[data]\n"
345
+ "0: ipm %[cc]\n"
346
+ " srl %[cc],28\n"
347
+ "1:\n"
348
+ EX_TABLE(0b, 1b)
349
+ : [cc] "+d" (cc), [len] "+d" (len)
350
+ : [ioaddr] "d" (ioaddr), [data] "Q" (*data)
351
+ : "cc");
352
+ *status = len >> 24 & 0xff;
353
+ return cc;
354
+}
355
+
356
+int zpci_write_block(volatile void __iomem *dst,
357
+ const void *src, unsigned long len)
358
+{
359
+ u8 status;
360
+ int cc;
361
+
362
+ if (!static_branch_unlikely(&have_mio))
363
+ return zpci_write_block_fh(dst, src, len);
364
+
365
+ cc = __pcistb_mio(src, (__force u64) dst, len, &status);
366
+ if (cc)
367
+ zpci_err_insn(cc, status, 0, (__force u64) dst);
368
+
369
+ return (cc > 0) ? -EIO : cc;
370
+}
371
+EXPORT_SYMBOL_GPL(zpci_write_block);
372
+
373
+static inline void __pciwb_mio(void)
374
+{
375
+ unsigned long unused = 0;
376
+
377
+ asm volatile (".insn rre,0xb9d50000,%[op],%[op]\n"
378
+ : [op] "+d" (unused));
379
+}
380
+
381
+void zpci_barrier(void)
382
+{
383
+ if (static_branch_likely(&have_mio))
384
+ __pciwb_mio();
385
+}
386
+EXPORT_SYMBOL_GPL(zpci_barrier);