// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright(c) 2015, 2016 Intel Corporation. */ #include "hfi.h" /* additive distance between non-SOP and SOP space */ #define SOP_DISTANCE … #define PIO_BLOCK_MASK … /* number of QUADWORDs in a block */ #define PIO_BLOCK_QWS … /** * pio_copy - copy data block to MMIO space * @dd: hfi1 dev data * @pbuf: a number of blocks allocated within a PIO send context * @pbc: PBC to send * @from: source, must be 8 byte aligned * @count: number of DWORD (32-bit) quantities to copy from source * * Copy data from source to PIO Send Buffer memory, 8 bytes at a time. * Must always write full BLOCK_SIZE bytes blocks. The first block must * be written to the corresponding SOP=1 address. * * Known: * o pbuf->start always starts on a block boundary * o pbuf can wrap only at a block boundary */ void pio_copy(struct hfi1_devdata *dd, struct pio_buf *pbuf, u64 pbc, const void *from, size_t count) { … } /* * Handle carry bytes using shifts and masks. * * NOTE: the value the unused portion of carry is expected to always be zero. */ /* * "zero" shift - bit shift used to zero out upper bytes. Input is * the count of LSB bytes to preserve. */ #define zshift(x) … /* * "merge" shift - bit shift used to merge with carry bytes. Input is * the LSB byte count to move beyond. */ #define mshift(x) … /* * Jump copy - no-loop copy for < 8 bytes. */ static inline void jcopy(u8 *dest, const u8 *src, u32 n) { … } /* * Read nbytes from "from" and place them in the low bytes * of pbuf->carry. Other bytes are left as-is. Any previous * value in pbuf->carry is lost. * * NOTES: * o do not read from from if nbytes is zero * o from may _not_ be u64 aligned. */ static inline void read_low_bytes(struct pio_buf *pbuf, const void *from, unsigned int nbytes) { … } /* * Read nbytes bytes from "from" and put them at the end of pbuf->carry. * It is expected that the extra read does not overfill carry. * * NOTES: * o from may _not_ be u64 aligned * o nbytes may span a QW boundary */ static inline void read_extra_bytes(struct pio_buf *pbuf, const void *from, unsigned int nbytes) { … } /* * Write a quad word using parts of pbuf->carry and the next 8 bytes of src. * Put the unused part of the next 8 bytes of src into the LSB bytes of * pbuf->carry with the upper bytes zeroed.. * * NOTES: * o result must keep unused bytes zeroed * o src must be u64 aligned */ static inline void merge_write8( struct pio_buf *pbuf, void __iomem *dest, const void *src) { … } /* * Write a quad word using all bytes of carry. */ static inline void carry8_write8(union mix carry, void __iomem *dest) { … } /* * Write a quad word using all the valid bytes of carry. If carry * has zero valid bytes, nothing is written. * Returns 0 on nothing written, non-zero on quad word written. */ static inline int carry_write8(struct pio_buf *pbuf, void __iomem *dest) { … } /* * Segmented PIO Copy - start * * Start a PIO copy. * * @pbuf: destination buffer * @pbc: the PBC for the PIO buffer * @from: data source, QWORD aligned * @nbytes: bytes to copy */ void seg_pio_copy_start(struct pio_buf *pbuf, u64 pbc, const void *from, size_t nbytes) { … } /* * Mid copy helper, "mixed case" - source is 64-bit aligned but carry * bytes are non-zero. * * Whole u64s must be written to the chip, so bytes must be manually merged. * * @pbuf: destination buffer * @from: data source, is QWORD aligned. * @nbytes: bytes to copy * * Must handle nbytes < 8. */ static void mid_copy_mix(struct pio_buf *pbuf, const void *from, size_t nbytes) { … } /* * Mid copy helper, "straight case" - source pointer is 64-bit aligned * with no carry bytes. * * @pbuf: destination buffer * @from: data source, is QWORD aligned * @nbytes: bytes to copy * * Must handle nbytes < 8. */ static void mid_copy_straight(struct pio_buf *pbuf, const void *from, size_t nbytes) { … } /* * Segmented PIO Copy - middle * * Must handle any aligned tail and any aligned source with any byte count. * * @pbuf: a number of blocks allocated within a PIO send context * @from: data source * @nbytes: number of bytes to copy */ void seg_pio_copy_mid(struct pio_buf *pbuf, const void *from, size_t nbytes) { … } /* * Segmented PIO Copy - end * * Write any remainder (in pbuf->carry) and finish writing the whole block. * * @pbuf: a number of blocks allocated within a PIO send context */ void seg_pio_copy_end(struct pio_buf *pbuf) { … }