1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright(c) 2015, 2016 Intel Corporation.
8 /* additive distance between non-SOP and SOP space */
9 #define SOP_DISTANCE (TXE_PIO_SIZE / 2)
10 #define PIO_BLOCK_MASK (PIO_BLOCK_SIZE - 1)
11 /* number of QUADWORDs in a block */
12 #define PIO_BLOCK_QWS (PIO_BLOCK_SIZE / sizeof(u64))
15 * pio_copy - copy data block to MMIO space
17 * @pbuf: a number of blocks allocated within a PIO send context
19 * @from: source, must be 8 byte aligned
20 * @count: number of DWORD (32-bit) quantities to copy from source
22 * Copy data from source to PIO Send Buffer memory, 8 bytes at a time.
23 * Must always write full BLOCK_SIZE bytes blocks. The first block must
24 * be written to the corresponding SOP=1 address.
27 * o pbuf->start always starts on a block boundary
28 * o pbuf can wrap only at a block boundary
30 void pio_copy(struct hfi1_devdata
*dd
, struct pio_buf
*pbuf
, u64 pbc
,
31 const void *from
, size_t count
)
33 void __iomem
*dest
= pbuf
->start
+ SOP_DISTANCE
;
34 void __iomem
*send
= dest
+ PIO_BLOCK_SIZE
;
35 void __iomem
*dend
; /* 8-byte data end */
41 /* calculate where the QWORD data ends - in SOP=1 space */
42 dend
= dest
+ ((count
>> 1) * sizeof(u64
));
46 * all QWORD data is within the SOP block, does *not*
47 * reach the end of the SOP block
51 writeq(*(u64
*)from
, dest
);
56 * No boundary checks are needed here:
57 * 0. We're not on the SOP block boundary
58 * 1. The possible DWORD dangle will still be within
60 * 2. We cannot wrap except on a block boundary.
63 /* QWORD data extends _to_ or beyond the SOP block */
65 /* write 8-byte SOP chunk data */
67 writeq(*(u64
*)from
, dest
);
71 /* drop out of the SOP range */
76 * If the wrap comes before or matches the data end,
77 * copy until until the wrap, then wrap.
79 * If the data ends at the end of the SOP above and
80 * the buffer wraps, then pbuf->end == dend == dest
81 * and nothing will get written, but we will wrap in
82 * case there is a dangling DWORD.
84 if (pbuf
->end
<= dend
) {
85 while (dest
< pbuf
->end
) {
86 writeq(*(u64
*)from
, dest
);
91 dest
-= pbuf
->sc
->size
;
92 dend
-= pbuf
->sc
->size
;
95 /* write 8-byte non-SOP, non-wrap chunk data */
97 writeq(*(u64
*)from
, dest
);
102 /* at this point we have wrapped if we are going to wrap */
104 /* write dangling u32, if any */
109 val
.val32
[0] = *(u32
*)from
;
110 writeq(val
.val64
, dest
);
114 * fill in rest of block, no need to check pbuf->end
115 * as we only wrap on a block boundary
117 while (((unsigned long)dest
& PIO_BLOCK_MASK
) != 0) {
122 /* finished with this buffer */
123 this_cpu_dec(*pbuf
->sc
->buffers_allocated
);
128 * Handle carry bytes using shifts and masks.
130 * NOTE: the value the unused portion of carry is expected to always be zero.
134 * "zero" shift - bit shift used to zero out upper bytes. Input is
135 * the count of LSB bytes to preserve.
137 #define zshift(x) (8 * (8 - (x)))
140 * "merge" shift - bit shift used to merge with carry bytes. Input is
141 * the LSB byte count to move beyond.
143 #define mshift(x) (8 * (x))
146 * Jump copy - no-loop copy for < 8 bytes.
148 static inline void jcopy(u8
*dest
, const u8
*src
, u32 n
)
175 * Read nbytes from "from" and place them in the low bytes
176 * of pbuf->carry. Other bytes are left as-is. Any previous
177 * value in pbuf->carry is lost.
180 * o do not read from from if nbytes is zero
181 * o from may _not_ be u64 aligned.
183 static inline void read_low_bytes(struct pio_buf
*pbuf
, const void *from
,
186 pbuf
->carry
.val64
= 0;
187 jcopy(&pbuf
->carry
.val8
[0], from
, nbytes
);
188 pbuf
->carry_bytes
= nbytes
;
192 * Read nbytes bytes from "from" and put them at the end of pbuf->carry.
193 * It is expected that the extra read does not overfill carry.
196 * o from may _not_ be u64 aligned
197 * o nbytes may span a QW boundary
199 static inline void read_extra_bytes(struct pio_buf
*pbuf
,
200 const void *from
, unsigned int nbytes
)
202 jcopy(&pbuf
->carry
.val8
[pbuf
->carry_bytes
], from
, nbytes
);
203 pbuf
->carry_bytes
+= nbytes
;
207 * Write a quad word using parts of pbuf->carry and the next 8 bytes of src.
208 * Put the unused part of the next 8 bytes of src into the LSB bytes of
209 * pbuf->carry with the upper bytes zeroed..
212 * o result must keep unused bytes zeroed
213 * o src must be u64 aligned
215 static inline void merge_write8(
216 struct pio_buf
*pbuf
,
223 temp
= pbuf
->carry
.val64
| (new << mshift(pbuf
->carry_bytes
));
225 pbuf
->carry
.val64
= new >> zshift(pbuf
->carry_bytes
);
229 * Write a quad word using all bytes of carry.
231 static inline void carry8_write8(union mix carry
, void __iomem
*dest
)
233 writeq(carry
.val64
, dest
);
237 * Write a quad word using all the valid bytes of carry. If carry
238 * has zero valid bytes, nothing is written.
239 * Returns 0 on nothing written, non-zero on quad word written.
241 static inline int carry_write8(struct pio_buf
*pbuf
, void __iomem
*dest
)
243 if (pbuf
->carry_bytes
) {
244 /* unused bytes are always kept zeroed, so just write */
245 writeq(pbuf
->carry
.val64
, dest
);
253 * Segmented PIO Copy - start
257 * @pbuf: destination buffer
258 * @pbc: the PBC for the PIO buffer
259 * @from: data source, QWORD aligned
260 * @nbytes: bytes to copy
262 void seg_pio_copy_start(struct pio_buf
*pbuf
, u64 pbc
,
263 const void *from
, size_t nbytes
)
265 void __iomem
*dest
= pbuf
->start
+ SOP_DISTANCE
;
266 void __iomem
*send
= dest
+ PIO_BLOCK_SIZE
;
267 void __iomem
*dend
; /* 8-byte data end */
272 /* calculate where the QWORD data ends - in SOP=1 space */
273 dend
= dest
+ ((nbytes
>> 3) * sizeof(u64
));
277 * all QWORD data is within the SOP block, does *not*
278 * reach the end of the SOP block
281 while (dest
< dend
) {
282 writeq(*(u64
*)from
, dest
);
287 * No boundary checks are needed here:
288 * 0. We're not on the SOP block boundary
289 * 1. The possible DWORD dangle will still be within
291 * 2. We cannot wrap except on a block boundary.
294 /* QWORD data extends _to_ or beyond the SOP block */
296 /* write 8-byte SOP chunk data */
297 while (dest
< send
) {
298 writeq(*(u64
*)from
, dest
);
302 /* drop out of the SOP range */
303 dest
-= SOP_DISTANCE
;
304 dend
-= SOP_DISTANCE
;
307 * If the wrap comes before or matches the data end,
308 * copy until until the wrap, then wrap.
310 * If the data ends at the end of the SOP above and
311 * the buffer wraps, then pbuf->end == dend == dest
312 * and nothing will get written, but we will wrap in
313 * case there is a dangling DWORD.
315 if (pbuf
->end
<= dend
) {
316 while (dest
< pbuf
->end
) {
317 writeq(*(u64
*)from
, dest
);
322 dest
-= pbuf
->sc
->size
;
323 dend
-= pbuf
->sc
->size
;
326 /* write 8-byte non-SOP, non-wrap chunk data */
327 while (dest
< dend
) {
328 writeq(*(u64
*)from
, dest
);
333 /* at this point we have wrapped if we are going to wrap */
335 /* ...but it doesn't matter as we're done writing */
337 /* save dangling bytes, if any */
338 read_low_bytes(pbuf
, from
, nbytes
& 0x7);
340 pbuf
->qw_written
= 1 /*PBC*/ + (nbytes
>> 3);
344 * Mid copy helper, "mixed case" - source is 64-bit aligned but carry
345 * bytes are non-zero.
347 * Whole u64s must be written to the chip, so bytes must be manually merged.
349 * @pbuf: destination buffer
350 * @from: data source, is QWORD aligned.
351 * @nbytes: bytes to copy
353 * Must handle nbytes < 8.
355 static void mid_copy_mix(struct pio_buf
*pbuf
, const void *from
, size_t nbytes
)
357 void __iomem
*dest
= pbuf
->start
+ (pbuf
->qw_written
* sizeof(u64
));
358 void __iomem
*dend
; /* 8-byte data end */
359 unsigned long qw_to_write
= nbytes
>> 3;
360 unsigned long bytes_left
= nbytes
& 0x7;
362 /* calculate 8-byte data end */
363 dend
= dest
+ (qw_to_write
* sizeof(u64
));
365 if (pbuf
->qw_written
< PIO_BLOCK_QWS
) {
367 * Still within SOP block. We don't need to check for
368 * wrap because we are still in the first block and
369 * can only wrap on block boundaries.
371 void __iomem
*send
; /* SOP end */
375 * calculate the end of data or end of block, whichever
378 send
= pbuf
->start
+ PIO_BLOCK_SIZE
;
379 xend
= min(send
, dend
);
381 /* shift up to SOP=1 space */
382 dest
+= SOP_DISTANCE
;
383 xend
+= SOP_DISTANCE
;
385 /* write 8-byte chunk data */
386 while (dest
< xend
) {
387 merge_write8(pbuf
, dest
, from
);
392 /* shift down to SOP=0 space */
393 dest
-= SOP_DISTANCE
;
396 * At this point dest could be (either, both, or neither):
402 * If the wrap comes before or matches the data end,
403 * copy until until the wrap, then wrap.
405 * If dest is at the wrap, we will fall into the if,
406 * not do the loop, when wrap.
408 * If the data ends at the end of the SOP above and
409 * the buffer wraps, then pbuf->end == dend == dest
410 * and nothing will get written.
412 if (pbuf
->end
<= dend
) {
413 while (dest
< pbuf
->end
) {
414 merge_write8(pbuf
, dest
, from
);
419 dest
-= pbuf
->sc
->size
;
420 dend
-= pbuf
->sc
->size
;
423 /* write 8-byte non-SOP, non-wrap chunk data */
424 while (dest
< dend
) {
425 merge_write8(pbuf
, dest
, from
);
430 pbuf
->qw_written
+= qw_to_write
;
432 /* handle carry and left-over bytes */
433 if (pbuf
->carry_bytes
+ bytes_left
>= 8) {
436 /* there is enough to fill another qw - fill carry */
437 nread
= 8 - pbuf
->carry_bytes
;
438 read_extra_bytes(pbuf
, from
, nread
);
441 * One more write - but need to make sure dest is correct.
442 * Check for wrap and the possibility the write
443 * should be in SOP space.
445 * The two checks immediately below cannot both be true, hence
446 * the else. If we have wrapped, we cannot still be within the
447 * first block. Conversely, if we are still in the first block,
448 * we cannot have wrapped. We do the wrap check first as that
451 /* adjust if we have wrapped */
452 if (dest
>= pbuf
->end
)
453 dest
-= pbuf
->sc
->size
;
454 /* jump to the SOP range if within the first block */
455 else if (pbuf
->qw_written
< PIO_BLOCK_QWS
)
456 dest
+= SOP_DISTANCE
;
458 /* flush out full carry */
459 carry8_write8(pbuf
->carry
, dest
);
462 /* now adjust and read the rest of the bytes into carry */
464 from
+= nread
; /* from is now not aligned */
465 read_low_bytes(pbuf
, from
, bytes_left
);
467 /* not enough to fill another qw, append the rest to carry */
468 read_extra_bytes(pbuf
, from
, bytes_left
);
473 * Mid copy helper, "straight case" - source pointer is 64-bit aligned
474 * with no carry bytes.
476 * @pbuf: destination buffer
477 * @from: data source, is QWORD aligned
478 * @nbytes: bytes to copy
480 * Must handle nbytes < 8.
482 static void mid_copy_straight(struct pio_buf
*pbuf
,
483 const void *from
, size_t nbytes
)
485 void __iomem
*dest
= pbuf
->start
+ (pbuf
->qw_written
* sizeof(u64
));
486 void __iomem
*dend
; /* 8-byte data end */
488 /* calculate 8-byte data end */
489 dend
= dest
+ ((nbytes
>> 3) * sizeof(u64
));
491 if (pbuf
->qw_written
< PIO_BLOCK_QWS
) {
493 * Still within SOP block. We don't need to check for
494 * wrap because we are still in the first block and
495 * can only wrap on block boundaries.
497 void __iomem
*send
; /* SOP end */
501 * calculate the end of data or end of block, whichever
504 send
= pbuf
->start
+ PIO_BLOCK_SIZE
;
505 xend
= min(send
, dend
);
507 /* shift up to SOP=1 space */
508 dest
+= SOP_DISTANCE
;
509 xend
+= SOP_DISTANCE
;
511 /* write 8-byte chunk data */
512 while (dest
< xend
) {
513 writeq(*(u64
*)from
, dest
);
518 /* shift down to SOP=0 space */
519 dest
-= SOP_DISTANCE
;
522 * At this point dest could be (either, both, or neither):
528 * If the wrap comes before or matches the data end,
529 * copy until until the wrap, then wrap.
531 * If dest is at the wrap, we will fall into the if,
532 * not do the loop, when wrap.
534 * If the data ends at the end of the SOP above and
535 * the buffer wraps, then pbuf->end == dend == dest
536 * and nothing will get written.
538 if (pbuf
->end
<= dend
) {
539 while (dest
< pbuf
->end
) {
540 writeq(*(u64
*)from
, dest
);
545 dest
-= pbuf
->sc
->size
;
546 dend
-= pbuf
->sc
->size
;
549 /* write 8-byte non-SOP, non-wrap chunk data */
550 while (dest
< dend
) {
551 writeq(*(u64
*)from
, dest
);
556 /* we know carry_bytes was zero on entry to this routine */
557 read_low_bytes(pbuf
, from
, nbytes
& 0x7);
559 pbuf
->qw_written
+= nbytes
>> 3;
563 * Segmented PIO Copy - middle
565 * Must handle any aligned tail and any aligned source with any byte count.
567 * @pbuf: a number of blocks allocated within a PIO send context
569 * @nbytes: number of bytes to copy
571 void seg_pio_copy_mid(struct pio_buf
*pbuf
, const void *from
, size_t nbytes
)
573 unsigned long from_align
= (unsigned long)from
& 0x7;
575 if (pbuf
->carry_bytes
+ nbytes
< 8) {
576 /* not enough bytes to fill a QW */
577 read_extra_bytes(pbuf
, from
, nbytes
);
582 /* misaligned source pointer - align it */
583 unsigned long to_align
;
585 /* bytes to read to align "from" */
586 to_align
= 8 - from_align
;
589 * In the advance-to-alignment logic below, we do not need
590 * to check if we are using more than nbytes. This is because
591 * if we are here, we already know that carry+nbytes will
592 * fill at least one QW.
594 if (pbuf
->carry_bytes
+ to_align
< 8) {
595 /* not enough align bytes to fill a QW */
596 read_extra_bytes(pbuf
, from
, to_align
);
600 /* bytes to fill carry */
601 unsigned long to_fill
= 8 - pbuf
->carry_bytes
;
602 /* bytes left over to be read */
603 unsigned long extra
= to_align
- to_fill
;
607 read_extra_bytes(pbuf
, from
, to_fill
);
610 /* may not be enough valid bytes left to align */
614 /* ...now write carry */
615 dest
= pbuf
->start
+ (pbuf
->qw_written
* sizeof(u64
));
618 * The two checks immediately below cannot both be
619 * true, hence the else. If we have wrapped, we
620 * cannot still be within the first block.
621 * Conversely, if we are still in the first block, we
622 * cannot have wrapped. We do the wrap check first
623 * as that is more likely.
625 /* adjust if we've wrapped */
626 if (dest
>= pbuf
->end
)
627 dest
-= pbuf
->sc
->size
;
628 /* jump to SOP range if within the first block */
629 else if (pbuf
->qw_written
< PIO_BLOCK_QWS
)
630 dest
+= SOP_DISTANCE
;
632 carry8_write8(pbuf
->carry
, dest
);
635 /* read any extra bytes to do final alignment */
636 /* this will overwrite anything in pbuf->carry */
637 read_low_bytes(pbuf
, from
, extra
);
641 * If no bytes are left, return early - we are done.
642 * NOTE: This short-circuit is *required* because
643 * "extra" may have been reduced in size and "from"
644 * is not aligned, as required when leaving this
651 /* at this point, from is QW aligned */
654 if (pbuf
->carry_bytes
)
655 mid_copy_mix(pbuf
, from
, nbytes
);
657 mid_copy_straight(pbuf
, from
, nbytes
);
661 * Segmented PIO Copy - end
663 * Write any remainder (in pbuf->carry) and finish writing the whole block.
665 * @pbuf: a number of blocks allocated within a PIO send context
667 void seg_pio_copy_end(struct pio_buf
*pbuf
)
669 void __iomem
*dest
= pbuf
->start
+ (pbuf
->qw_written
* sizeof(u64
));
672 * The two checks immediately below cannot both be true, hence the
673 * else. If we have wrapped, we cannot still be within the first
674 * block. Conversely, if we are still in the first block, we
675 * cannot have wrapped. We do the wrap check first as that is
678 /* adjust if we have wrapped */
679 if (dest
>= pbuf
->end
)
680 dest
-= pbuf
->sc
->size
;
681 /* jump to the SOP range if within the first block */
682 else if (pbuf
->qw_written
< PIO_BLOCK_QWS
)
683 dest
+= SOP_DISTANCE
;
685 /* write final bytes, if any */
686 if (carry_write8(pbuf
, dest
)) {
689 * NOTE: We do not need to recalculate whether dest needs
690 * SOP_DISTANCE or not.
692 * If we are in the first block and the dangle write
693 * keeps us in the same block, dest will need
694 * to retain SOP_DISTANCE in the loop below.
696 * If we are in the first block and the dangle write pushes
697 * us to the next block, then loop below will not run
698 * and dest is not used. Hence we do not need to update
701 * If we are past the first block, then SOP_DISTANCE
702 * was never added, so there is nothing to do.
706 /* fill in rest of block */
707 while (((unsigned long)dest
& PIO_BLOCK_MASK
) != 0) {
712 /* finished with this buffer */
713 this_cpu_dec(*pbuf
->sc
->buffers_allocated
);