blob: ae9fc11721ffa714ab56076ae6e81cd746cbdf1c [file] [log] [blame]
/*********************************************************************
*
* (C) Copyright IBM Corp. 2007,2010
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses>.
*
********************************************************************/
#ifndef _DMA_DESCRIPTORS_H_ /* Prevent multiple inclusion */
#define _DMA_DESCRIPTORS_H_
/*!
* \file spi/DMA_Descriptors.h
*
* \brief DMA SPI Descriptor Definitions and Inline Functions
*
* This header file contains the definition of the DMA_InjDescriptor_t, which is
* put into the tail of an injection fifo to initiate a DMA transfer.
*
* The following defines the terms used for describing the various kinds of
* descriptors:
* - "Torus" means the transfer is between nodes.
* - "Local" means the transfer is within the same node.
* - "Direct-put" means the data is put directly into the destination node's
* memory.
* - "MemFifo" means the packets are put into the destination node's reception
* fifo.
* - "Remote-get" means the packet payload contains an injection descriptor
* to be injected into the destination node's injection fifo.
* - Prefetch-only" means the payload is just pre-fetched into L3. It is not
* transferred to the destination node.
*
* The following are the functions provided for creating injection descriptors:
* - DMA_TorusDirectPutDescriptor
* - DMA_LocalDirectPutDescriptor
* - DMA_LocalPrefetchOnlyDescriptor
* - DMA_TorusRemoteGetDescriptor
* - DMA_LocalRemoteGetDescriptor
* - DMA_TorusMemFifoDescriptor
* - DMA_LocalMemFifoDescriptor
* - DMA_TorusDirectPutBcastDescriptor
* - DMA_TorusMemFifoBcastDescriptor
*
*
* There are also functions for setting or changing specific values in the
* injection descriptors.
*
*/
#include <common/namespace.h>
__BEGIN_DECLS
/*!
* \brief __INLINE__ definition
*
* Option 1:
* Make all functions be "static inline":
* - They are inlined if the compiler can do it
* - If the compiler does not inline it, a single copy of the function is
* placed in the translation unit (eg. xxx.c)for use within that unit.
* The function is not externalized for use by another unit...we want this
* so we don't end up with multiple units exporting the same function,
* which would result in linker errors.
*
* Option 2:
* A GNU C model: Use "extern inline" in a common header (this one) and provide
* a definition in a .c file somewhere, perhaps using macros to ensure that the
* same code is used in each case. For instance, in the header file:
*
* \verbatim
#ifndef INLINE
# define INLINE extern inline
#endif
INLINE int max(int a, int b) {
return a > b ? a : b;
}
\endverbatim
*
* ...and in exactly one source file (in runtime/SPI), that is included in a
* library...
*
* \verbatim
#define INLINE
#include "header.h"
\endverbatim
*
* This allows inlining, where possible, but when not possible, only one
* instance of the function is in storage (in the library).
*/
#ifndef __INLINE__
#define __INLINE__ extern inline
#endif
#include <bpcore/bgp_types.h>
#include <common/alignment.h>
#include <common/bgp_bitnumbers.h>
#include <spi/DMA_Packet.h>
#include <spi/DMA_Assert.h>
/*!
* \brief Packet Header - Checksum Skip Bytes
*
* Default number of 2 byte units to skip from the top of a packet before
* including the packet bytes into the running checksum of the torus
* injection fifo where this packet is injected.
*
* 8 corresponds to skipping 16 bytes, which is the DMA packet header size
* (hardware header + software header).
*/
#define DMA_CSUM_SKIP 8
/*!
* \brief Packet Header - Checksum Skip Packet
*
* Default value for the torus injection checksum skip packet bit.
* - 0 includes the packet (excluding the portion designated by DMA_CSUM_SKIP)
* in the checksum.
* - 1 excludes the entire packet from the checksum.
*/
#define DMA_CSUM_BIT 0
/*!
* \brief DMA Injection Descriptor Structure
*
*/
typedef struct DMA_InjDescriptor_t
{
union {
unsigned word1; /*!< For accessing fields as 32-bit word */
struct {
unsigned rsvd0 : 24; /*!< 3 bytes: unused */
unsigned rsvd1 : 6; /*!< Bits 0-5: unused flags */
unsigned prefetch_only : 1; /*!< Bit 6: prefetch only, on local
memcopy:
0 = Data is both read and written,
1 = Data is only read.
This bit is ignored for torus
packets. */
unsigned local_memcopy : 1; /*!< Bit 7: local memory copy bit:
0 = The message is a torus message,
1 = The message is a local copy. */
};
};
union {
unsigned word2; /*!< For accessing fields as 32-bit word */
struct {
unsigned rsvd2 : 24; /*!< 3 bytes: unused */
unsigned idma_counterId : 8; /*!< 1 byte: Injection Counter Id. */
};
};
unsigned base_offset : 32; /*!< 4 bytes: pointer to base address of
message payload. This gets added to
the base address associated with the
idma_counterId injection counter. */
unsigned msg_length : 32; /*!< 4 bytes: message length (in bytes) */
DMA_PacketHeader_t hwHdr; /*!< DMA Hardware Packet Header */
}
DMA_InjDescriptor_t ALIGN_QUADWORD;
/*!
* \todo Change to ALIGN_L1D_CACHE when it works.
*
*/
/*!
* \brief Static Info from Personality
*
* The following structure defines information from the personality.
* It is intended to be static so, once the info is retrieved from
* the personality, it does not need to be retrieved again (it is a
* system call to retrieve personality info).
*
*/
typedef struct DMA_PersonalityInfo_t
{
unsigned int personalityRetrieved; /*!< 0 = Personality Info not
retrieved into this
structure yet.
1 = Personality Info in this
structure is valid. */
uint8_t nodeXCoordinate; /*!< X coord of the calling node. */
uint8_t nodeYCoordinate; /*!< Y coord of the calling node. */
uint8_t nodeZCoordinate; /*!< Z coord of the calling node. */
uint8_t xNodes; /*!< X dimension of the block. */
uint8_t yNodes; /*!< Y dimension of the block. */
uint8_t zNodes; /*!< Z dimension of the block. */
}
DMA_PersonalityInfo_t;
/*!
* \brief Create a DMA Descriptor For a Torus Direct Put Message
*
* A torus direct put message is one that is sent to another node and its data
* is directly put into memory by the DMA on the destination node...it does
* not go into a reception fifo.
*
* A torus direct-put DMA descriptor contains the following:
*
* - 16 bytes of control information:
* - prefetch_only = 0
* - local_memcopy = 0
* - idma_counterId = Injection counter ID associated with the data being
* sent. This counter contains the base address of the
* message and the message length. Set based on caller's
* inj_ctr_grp_id and inj_ctr_id.
* - base_offset = Message offset (from the injection counter's base
* address). Set to caller's send_offset.
* - msg_length = Message length. Set to caller's msg_len.
*
* - 8 byte torus hardware header
* - CSum_Skip = DMA_CSUM_SKIP.
* - Sk = DMA_CSUM_BIT.
* - Hint = Set to caller's "hints".
* - Pid0, Pid1 = Set based on caller's "recv_ctr_grp_id" (see note).
* - Chunks = Set to largest size consistent with msg_len.
* - Dm = 1 (Indicates a direct-put packet).
* - Dynamic = Set based on caller's "vc".
* - VC = Set to caller's "vc".
* - X,Y,Z = Set to caller's "x", "y", "z".
*
* - 8 byte software header (initial values used by iDMA).
* - Put_Offset = Destination message offset (from the reception
* counter's base address). Set to caller's recv_offset.
* - rDMA_Counter = Reception counter ID. This counter is located on the
* destination node and contains the base address of the
* message and the message length. Set based on caller's
* recv_ctr_grp_id and recv_ctr_id.
* - Payload_Bytes = Number of valid bytes in the payload. Set by iDMA.
* - Flags = Pacing = 0.
* Remote-Get = 0.
* - iDMA_Fifo_ID = 0 (not used).
* - Func_Id = 0 (not used).
*
* This function creates the above descriptor.
*
* \param[in,out] desc Pointer to the storage where the descriptor
* will be created.
* \param[in] x The destination's x coordinate (8 bits).
* \param[in] y The destination's y coordinate (8 bits).
* \param[in] z The destination's z coordinate (8 bits).
* \param[in] hints Hint bits for torus routing (6 bits).
* Each bit corresponds to x+, x-, y+, y-,
* z+, z-. If a bit is set, it indicates that
* the packet wants to travel along the
* corresponding direction. If all bits are
* zero, the hardware calculates the hint bits.
* Both of x+ and x- cannot be set at the same
* time...same with y and z.
* \param[in] vc The virtual channel that the packet must go
* into if it fails to win the bypass
* arbitration in the receiving node.
* - 0 = Virtual channel dynamic 0
* - 1 = Virtual channel dynamic 1
* - 2 = Virtual channel deterministic bubble
* - 3 = Virtual channel deterministic priority
* \param[in] inj_ctr_grp_id Injection counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] inj_ctr_id Injection counter ID (within the inj counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] send_offset Offset of the send payload from the pa_base
* associated with the specified injection
* counter.
* \param[in] recv_ctr_grp_id Reception counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] recv_ctr_id Reception counter ID (within the recv counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] recv_offset Offset of the payload from the pa_base
* associated with the specified reception
* counter.
* \param[in] msg_len Total message length (in bytes).
*
* \retval 0 Success
* \retval non-zero Failure
*
* \note By default, all payload bytes are included in the torus injection
* checksum. In the first byte of the torus hardware packet header,
* this corresponds to setting CSum_Skip = 0x8 (16 bytes) and Sk=0.
* The defaults can be changed by changing DMA_CSUM_SKIP and
* DMA_CSUM_BIT in this include file.
*
* \note By default, the packet size is set to the largest value consistent
* with the message size. For example,
* - if msg_len >= 209, there will be 8 32-byte chunks in each packet,
* with the possible exception of the last packet, which could contain
* fewer chunks (209... of payload + 16 header).
* - if 177 <= msg_len < 208, there will be 7 chunks in the packet, etc.
*
* \note By default, for direct-put DMA messages, the pid0 and pid1 bits in the
* torus hardware packet header are determined by the recv_ctr_grp_id:
* - if recv_ctr_grp_id = 0 => (pid0,pid1) = (0,0)
* - if recv_ctr_grp_id = 1 => (pid0,pid1) = (0,1)
* - if recv_ctr_grp_id = 2 => (pid0,pid1) = (1,0)
* - if recv_ctr_grp_id = 3 => (pid0,pid1) = (1,1)
* Pid0 determines into which physical torus fifo group on the destination
* node the packet is put, prior to the dma receiving it. Other than that,
* the only use for the pid bits is for debug, ie, if headers are being
* saved.
*/
int DMA_TorusDirectPutDescriptor(
DMA_InjDescriptor_t *desc,
unsigned int x,
unsigned int y,
unsigned int z,
unsigned int hints,
unsigned int vc,
unsigned int inj_ctr_grp_id,
unsigned int inj_ctr_id,
unsigned int send_offset,
unsigned int recv_ctr_grp_id,
unsigned int recv_ctr_id,
unsigned int recv_offset,
unsigned int msg_len
);
/*!
* \brief Create a DMA Descriptor For a Local Direct Put Message
*
* A local direct put message is one that is targeted within the same node, and
* its data is directly put into memory by the DMA...it does not go into a
* reception fifo. This is essentially a memcpy via DMA.
*
* A local direct-put DMA descriptor contains the following:
*
* - 16 bytes of control information:
* - prefetch_only = 0
* - local_memcopy = 1
* - idma_counterId = Injection counter ID associated with the data being
* sent. This counter contains the base address of the
* message and the message length. Set based on caller's
* inj_ctr_grp_id and inj_ctr_id.
* - base_offset = Message offset (from the injection counter's base
* address). Set to caller's send_offset.
* - msg_length = Message length. Set to caller's msg_len.
*
* - 8 byte torus hardware header
* - CSum_Skip = 0 (not used).
* - Sk = 0 (not used).
* - Hint = 0 (not used).
* - Pid0, Pid1 = Set based on caller's "recv_ctr_grp_id".
* - Chunks = Set to largest size consistent with msg_len.
* - Dm = 1 (Indicates a direct-put packet).
* - Dynamic = 0 (not used).
* - VC = 0 (not used).
* - X,Y,Z = 0 (not used).
*
* - 8 byte software header (initial values used by iDMA).
* - Put_Offset = Destination message offset (from the reception
* counter's base address). Set to caller's recv_offset.
* - rDMA_Counter = Reception counter ID. This counter is located on the
* destination node and contains the base address of the
* message and the message length.. Set based on caller's
* recv_ctr_grp_id and recv_ctr_id.
* - Payload_Bytes = Number of valid bytes in the payload. Set by iDMA.
* - Flags = Pacing = 0.
* Remote-Get = 0.
* - iDMA_Fifo_ID = 0 (not used).
* - Func_Id = 0 (not used).
*
* This function creates the above descriptor.
*
* \param[in,out] desc Pointer to the storage where the descriptor
* will be created.
* \param[in] inj_ctr_grp_id Injection counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] inj_ctr_id Injection counter ID (within the inj counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] send_offset Offset of the send payload from the pa_base
* associated with the specified injection
* counter.
* \param[in] recv_ctr_grp_id Reception counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] recv_ctr_id Reception counter ID (within the recv counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] recv_offset Offset of the payload from the pa_base
* associated with the specified reception
* counter.
* \param[in] msg_len Total message length (in bytes).
*
* \retval 0 Success
* \retval non-zero Failure
*
* \note By default, the packet size is set to the largest value consistent
* with the message size. For example,
* - if msg_len >= 209, there will be 8 32-byte chunks in each packet,
* with the possible exception of the last packet, which could contain
* fewer chunks (209... of payload + 16 header).
* - if 177 <= msg_len < 208, there will be 7 chunks in the packet, etc.
*
* \note By default, for direct-put DMA messages, the pid0 and pid1 bits in the
* torus hardware packet header are determined by the recv_ctr_grp_id:
* - if recv_ctr_grp_id = 0 => (pid0,pid1) = (0,0)
* - if recv_ctr_grp_id = 1 => (pid0,pid1) = (0,1)
* - if recv_ctr_grp_id = 2 => (pid0,pid1) = (1,0)
* - if recv_ctr_grp_id = 3 => (pid0,pid1) = (1,1)
* The only use for the pid bits is for debug, ie, if headers are
* being saved.
*/
int DMA_LocalDirectPutDescriptor(
DMA_InjDescriptor_t *desc,
unsigned int inj_ctr_grp_id,
unsigned int inj_ctr_id,
unsigned int send_offset,
unsigned int recv_ctr_grp_id,
unsigned int recv_ctr_id,
unsigned int recv_offset,
unsigned int msg_len
);
/*!
* \brief Create a DMA Descriptor For a Local L3 Prefetch Only Message
*
* A local prefetch is one in which the DMA simply prefetches the send buffer
* into L3.
*
* A local prefetch DMA descriptor contains the following:
*
* - 16 bytes of control information:
* - prefetch_only = 1
* - local_memcopy = 1
* - idma_counterId = Injection counter ID associated with the message being
* prefetched. This counter contains the base address of
* the message and the message length. Set based on caller's
* inj_ctr_grp_id and inj_ctr_id.
* - base_offset = Message offset (from the injection counter's base
* address). Set to caller's send_offset.
* - msg_length = Message length. Set to caller's msg_len.
*
* - 8 byte torus hardware header
* - CSum_Skip = 0 (not used).
* - Sk = 0 (not used).
* - Hint = 0 (not used).
* - Pid0, Pid1 = 0 (not used).
* - Chunks = Set to largest size consistent with msg_len.
* - Dm = 1 (Indicates a DMA packet).
* - Dynamic = 0 (not used).
* - VC = 0 (not used).
* - X,Y,Z = 0 (not used).
*
* - 8 byte software header (initial values used by iDMA).
* - Put_Offset = 0 (not used).
* - rDMA_Counter = 0 (not used).
* - Payload_Bytes = 0 (not used).
* - Flags = Pacing = 0.
* Remote-Get = 0.
* - iDMA_Fifo_ID = 0 (not used).
* - Func_Id = 0 (not used).
*
* This function creates the above descriptor.
*
* \param[in,out] desc Pointer to the storage where the descriptor
* will be created.
* \param[in] inj_ctr_grp_id Injection counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] inj_ctr_id Injection counter ID (within the inj counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] send_offset Offset of the send payload from the pa_base
* associated with the specified injection
* counter.
* \param[in] msg_len Total message length (in bytes).
*
* \retval 0 Success
* \retval non-zero Failure
*
* \note By default, the packet size is set to the largest value consistent
* with the message size. For example,
* - if msg_len >= 209, there will be 8 32-byte chunks in each packet,
* with the possible exception of the last packet, which could contain
* fewer chunks (209... of payload + 16 header).
* - if 177 <= msg_len < 208, there will be 7 chunks in the packet, etc.
*
*/
int DMA_LocalPrefetchOnlyDescriptor(
DMA_InjDescriptor_t *desc,
unsigned int inj_ctr_grp_id,
unsigned int inj_ctr_id,
unsigned int send_offset,
unsigned int msg_len
);
/*!
* \brief Create a DMA Descriptor For a Torus Remote-Get Message
*
* A torus remote-get message is one that is sent to another node and its data
* is directly put by the DMA into an injection fifo on the destination
* node...it does not go into a reception fifo. Therefore, the payload of this
* message is one (or more) descriptors for another message that is to be sent
* back to the originating node.
*
* By default, we assume that the payload of this remote get packet is a single
* descriptor. Thus, Chunks = (2)-1 (64 byte packet) and msg_length = 32.
* For remote gets whose payload is greater than 1 descriptor, the caller can
* change the packet Chunks and msg_length after this function builds the
* default descriptor.
*
* It is also assumed that the payload is NOT checksummed, since it is not
* always reproducible. Things like idma_counterId and base_offset may be
* different on another run, making checksumming inconsistent.
*
* A torus remote-get DMA descriptor contains the following:
*
* - 16 bytes of control information:
* - prefetch_only = 0
* - local_memcopy = 0
* - idma_counterId = Injection counter ID associated with the data being
* sent. This counter contains the base address of the
* message and the message length. Set based on caller's
* inj_ctr_grp_id and inj_ctr_id.
* - base_offset = Message offset (from the injection counter's base
* address). Set to caller's send_offset.
* - msg_length = 32.
*
* - 8 byte torus hardware header
* - CSum_Skip = 0 (not used because Sk is 1).
* - Sk = 1 (do not checksum this packet).
* - Hint = Set to caller's "hints".
* - Pid0, Pid1 = Set based on caller's "recv_inj_fifo_id" (see note).
* - Chunks = Set to (2)-1 = 1.
* - Dm = 1 (Indicates a DMA packet).
* - Dynamic = Set based on caller's "vc".
* - VC = Set to caller's "vc".
* - X,Y,Z = Set to caller's "x", "y", "z".
*
* - 8 byte software header (initial values used by iDMA).
* - Put_Offset = 0 (not used).
* - rDMA_Counter = 0 (not used).
* - Payload_Bytes = Number of valid bytes in the payload. Set by iDMA.
* - Flags = Pacing = 0.
* Remote-Get = 1.
* - iDMA_Fifo_ID = Injection fifo ID where the payload will be injected.
* Set based on caller's recv_inj_ctr_grp_id and
* recv_inj_ctr_id.
* - Func_Id = 0 (not used).
*
* This function creates the above descriptor.
*
* \param[in,out] desc Pointer to the storage where the descriptor
* will be created.
* \param[in] x The destination's x coordinate (8 bits).
* \param[in] y The destination's y coordinate (8 bits).
* \param[in] z The destination's z coordinate (8 bits).
* \param[in] hints Hint bits for torus routing (6 bits).
* Each bit corresponds to x+, x-, y+, y-,
* z+, z-. If a bit is set, it indicates that
* the packet wants to travel along the
* corresponding direction. If all bits are
* zero, the hardware calculates the hint bits.
* Both of x+ and x- cannot be set at the same
* time...same with y and z.
* \param[in] vc The virtual channel that the packet must go
* into if it fails to win the bypass
* arbitration in the receiving node.
* - 0 = Virtual channel dynamic 0
* - 1 = Virtual channel dynamic 1
* - 2 = Virtual channel deterministic bubble
* - 3 = Virtual channel deterministic priority
* \param[in] inj_ctr_grp_id Injection counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] inj_ctr_id Injection counter ID (within the inj counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] send_offset Offset of the send payload from the pa_base
* associated with the specified injection
* counter.
* \param[in] recv_inj_fifo_grp_id Injection fifo group ID where payload
* will be injected on destination node
* (0 to DMA_NUM_INJ_FIFO_GROUPS-1).
* \param[in] recv_inj_fifo_id Injection fifo ID (within the
* recv_inj_fifo_grp_id group)
* (0 to DMA_NUM_INJ_FIFOS_PER_GROUP-1).
*
* \retval 0 Success
* \retval non-zero Failure
*
* \note By default, for remote-get DMA messages, the pid0 and pid1 bits in the
* torus hardware packet header are determined by the recv_inj_fifo_grp_id:
* - if recv_inj_fifo_grp_id = 0 => (pid0,pid1) = (0,0)
* - if recv_inj_fifo_grp_id = 1 => (pid0,pid1) = (0,1)
* - if recv_inj_fifo_grp_id = 2 => (pid0,pid1) = (1,0)
* - if recv_inj_fifo_grp_id = 3 => (pid0,pid1) = (1,1)
* Pid0 determines into which physical torus fifo group on the destination
* node the packet is put, prior to the dma receiving it. Other than that,
* the only use for the pid bits is for debug, ie, if headers are being
* saved.
*/
int DMA_TorusRemoteGetDescriptor(
DMA_InjDescriptor_t *desc,
unsigned int x,
unsigned int y,
unsigned int z,
unsigned int hints,
unsigned int vc,
unsigned int inj_ctr_grp_id,
unsigned int inj_ctr_id,
unsigned int send_offset,
unsigned int recv_inj_fifo_grp_id,
unsigned int recv_inj_fifo_id
);
/*!
* \brief Create a DMA Descriptor For a Local Remote-Get Message
*
* A local remote-get message is one whose data is directly put by the DMA into
* an injection fifo on the local node...it does not go into a reception fifo.
* Therefore, the payload of this message is one (or more) descriptors for
* another message that is to be injected on the local node.
*
* By default, we assume that the payload of this remote get packet is a single
* descriptor. Thus, Chunks = (2)-1 (64 byte packet) and msg_length = 32.
* For remote gets whose payload is greater than 1 descriptor, the caller can
* change the packet Chunks and msg_length after this function builds the
* default descriptor.
*
* A local remote-get DMA descriptor contains the following:
*
* - 16 bytes of control information:
* - prefetch_only = 0
* - local_memcopy = 1
* - idma_counterId = Injection counter ID associated with the data being
* sent. This counter contains the base address of the
* message and the message length. Set based on caller's
* inj_ctr_grp_id and inj_ctr_id.
* - base_offset = Message offset (from the injection counter's base
* address). Set to caller's send_offset.
* - msg_length = 32.
*
* - 8 byte torus hardware header
* - CSum_Skip = 0 (not used).
* - Sk = 0 (not used).
* - Hint = 0 (Set to caller's "hints".
* - Pid0, Pid1 = Set based on caller's "recv_inj_fifo_id" (see note).
* - Chunks = Set to (2)-1 = 1.
* - Dm = 1 (Indicates a DMA packet).
* - Dynamic = 0 (not used).
* - VC = 0 (not used).
* - X,Y,Z = 0 (not used).
*
* - 8 byte software header (initial values used by iDMA).
* - Put_Offset = 0 (not used).
* - rDMA_Counter = 0 (not used).
* - Payload_Bytes = Number of valid bytes in the payload. Set by iDMA.
* - Flags = Pacing = 0.
* Remote-Get = 1.
* - iDMA_Fifo_ID = Injection fifo ID where the payload will be injected.
* Set based on caller's inj_ctr_grp_id and inj_ctr_id.
* - Func_Id = 0 (not used).
*
* This function creates the above descriptor.
*
* \param[in,out] desc Pointer to the storage where the descriptor
* will be created.
* \param[in] inj_ctr_grp_id Injection counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] inj_ctr_id Injection counter ID (within the inj counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] send_offset Offset of the send payload from the pa_base
* associated with the specified injection
* counter.
* \param[in] recv_inj_fifo_grp_id Injection fifo group ID where payload
* will be injected on local node
* (0 to DMA_NUM_INJ_FIFO_GROUPS-1).
* \param[in] recv_inj_fifo_id Injection fifo ID (within the
* recv_inj_fifo_grp_id group)
* (0 to DMA_NUM_INJ_FIFOS_PER_GROUP-1).
*
* \retval 0 Success
* \retval non-zero Failure
*
* \note By default, for remote-get DMA messages, the pid0 and pid1 bits in the
* hardware packet header are determined by the recv_inj_fifo_grp_id:
* - if recv_inj_fifo_grp_id = 0 => (pid0,pid1) = (0,0)
* - if recv_inj_fifo_grp_id = 1 => (pid0,pid1) = (0,1)
* - if recv_inj_fifo_grp_id = 2 => (pid0,pid1) = (1,0)
* - if recv_inj_fifo_grp_id = 3 => (pid0,pid1) = (1,1)
*
*/
int DMA_LocalRemoteGetDescriptor(
DMA_InjDescriptor_t *desc,
unsigned int inj_ctr_grp_id,
unsigned int inj_ctr_id,
unsigned int send_offset,
unsigned int recv_inj_fifo_grp_id,
unsigned int recv_inj_fifo_id
);
/*!
* \brief Create a DMA Descriptor For a Torus Memory Fifo Message
*
* A torus memory fifo message is one that is sent to another node and its data
* is put into a reception memory fifo by the DMA on the destination node.
*
* A torus memory fifo DMA descriptor contains the following:
*
* - 16 bytes of control information:
* - prefetch_only = 0
* - local_memcopy = 0
* - idma_counterId = Injection counter ID associated with the data being
* sent. This counter contains the base address of the
* message and the message length. Set based on caller's
* inj_ctr_grp_id and inj_ctr_id.
* - base_offset = Message offset (from the injection counter's base
* address). Set to caller's send_offset.
* - msg_length = Message length. Set to caller's msg_len.
*
* - 8 byte torus hardware header
* - CSum_Skip = DMA_CSUM_SKIP.
* - Sk = DMA_CSUM_BIT.
* - Hint = Set to caller's "hints".
* - Pid0, Pid1 = Set based on caller's "recv_fifo_grp_id" (see note).
* - Chunks = Set to largest size consistent with msg_len.
* - Dm = 0 (Indicates a memory fifo packet).
* - Dynamic = Set based on caller's "vc".
* - VC = Set to caller's "vc".
* - X,Y,Z = Set to caller's "x", "y", "z".
*
* - 8 byte software header (initial values used by iDMA).
* - Put_Offset = 0 (not used).
* - rDMA_Counter = 0 (not used).
* - Payload_Bytes = 0 (not used).
* - Flags = Pacing = 0.
* Remote-Get = 0.
* - iDMA_Fifo_ID = 0 (not used).
* - SW_Arg = User-defined 24 bits. Set to caller's sw_arg.
* - Func_Id = The registration ID of a function to receive control
* on the destination node to process the packet.
* Set to caller's function_id.
*
* This function creates the above descriptor.
*
* \param[in,out] desc Pointer to the storage where the descriptor
* will be created.
* \param[in] x The destination's x coordinate (8 bits).
* \param[in] y The destination's y coordinate (8 bits).
* \param[in] z The destination's z coordinate (8 bits).
* \param[in] recv_fifo_grp_id Reception fifo group ID
* (0 to DMA_NUM_REC_FIFO_GROUPS-1).
* \param[in] hints Hint bits for torus routing (6 bits).
* Each bit corresponds to x+, x-, y+, y-,
* z+, z-. If a bit is set, it indicates that
* the packet wants to travel along the
* corresponding direction. If all bits are
* zero, the hardware calculates the hint bits.
* Both of x+ and x- cannot be set at the same
* time...same with y and z.
* \param[in] vc The virtual channel that the packet must go
* into if it fails to win the bypass
* arbitration in the receiving node.
* - 0 = Virtual channel dynamic 0
* - 1 = Virtual channel dynamic 1
* - 2 = Virtual channel deterministic bubble
* - 3 = Virtual channel deterministic priority
* \param[in] sw_arg User-defined 24 bits to be placed into the
* packets (bits 8-31).
* \param[in] function_id Function id (8 bit registration ID) of the
* function to receive control on the
* destination node to process packets for this
* message.
* \param[in] inj_ctr_grp_id Injection counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] inj_ctr_id Injection counter ID (within the inj counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] send_offset Offset of the send payload from the pa_base
* associated with the specified injection
* counter.
* \param[in] msg_len Total message length (in bytes).
*
* \retval 0 Success
* \retval non-zero Failure
*
* \note By default, all payload bytes are included in the torus injection
* checksum. In the first byte of the torus hardware packet header,
* this corresponds to setting CSum_Skip = 0x8 (16 bytes) and Sk=0.
* The defaults can be changed by changing DMA_CSUM_SKIP and
* DMA_CSUM_BIT in this include file.
*
* \note By default, the packet size is set to the largest value consistent
* with the message size. For example,
* - if msg_len >= 209, there will be 8 32-byte chunks in each packet,
* with the possible exception of the last packet, which could contain
* fewer chunks (209... of payload + 16 header).
* - if 177 <= msg_len < 208, there will be 7 chunks in the packet, etc.
*
* \note By default, for DMA messages, the pid0 and pid1 bits in the
* torus hardware packet header are determined by the recv_fifo_grp_id:
* - if recv_fifo_grp_id = 0 => (pid0,pid1) = (0,0)
* - if recv_fifo_grp_id = 1 => (pid0,pid1) = (0,1)
* - if recv_fifo_grp_id = 2 => (pid0,pid1) = (1,0)
* - if recv_fifo_grp_id = 3 => (pid0,pid1) = (1,1)
* Pid0 determines into which physical torus fifo group on the destination
* node the packet is put, prior to the dma receiving it. Other than that,
* the only use for the pid bits is for debug, ie, if headers are being
* saved.
*/
int DMA_TorusMemFifoDescriptor(
DMA_InjDescriptor_t *desc,
unsigned int x,
unsigned int y,
unsigned int z,
unsigned int recv_fifo_grp_id,
unsigned int hints,
unsigned int vc,
unsigned int sw_arg,
unsigned int function_id,
unsigned int inj_ctr_grp_id,
unsigned int inj_ctr_id,
unsigned int send_offset,
unsigned int msg_len
);
/*!
* \brief Create a DMA Descriptor For a Local Memory Fifo Message
*
* A local memory fifo message is one whose data is put into a reception
* memory fifo on the same node by the DMA.
*
* A local memory fifo DMA descriptor contains the following:
*
* - 16 bytes of control information:
* - prefetch_only = 0
* - local_memcopy = 0
* - idma_counterId = Injection counter ID associated with the data being
* sent. This counter contains the base address of the
* message and the message length. Set based on caller's
* inj_ctr_grp_id and inj_ctr_id.
* - base_offset = Message offset (from the injection counter's base
* address). Set to caller's send_offset.
* - msg_length = Message length. Set to caller's msg_len.
*
* - 8 byte torus hardware header
* - CSum_Skip = 0 (not used).
* - Sk = 0 (not used).
* - Hint = 0 (not used).
* - Pid0, Pid1 = Set based on caller's "recv_fifo_grp_id" (see note).
* - Chunks = Set to largest size consistent with msg_len.
* - Dm = 0 (Indicates a memory fifo packet).
* - Dynamic = 0 (not used).
* - VC = 0 (not used).
* - X,Y,Z = 0 (not used).
*
* - 8 byte software header (initial values used by iDMA).
* - Put_Offset = 0 (not used).
* - rDMA_Counter = 0 (not used).
* - Payload_Bytes = 0 (not used).
* - Flags = Pacing = 0.
* Remote-Get = 0.
* - iDMA_Fifo_ID = 0 (not used).
* - SW_Arg = User-defined 24 bits. Set to caller's sw_arg.
* - Func_Id = The registration ID of a function to receive control
* on this local node to process the packet.
* Set to caller's function_id.
*
* This function creates the above descriptor.
*
* \param[in,out] desc Pointer to the storage where the descriptor
* will be created.
* \param[in] recv_fifo_grp_id Reception fifo group ID
* (0 to DMA_NUM_REC_FIFO_GROUPS-1).
* \param[in] sw_arg User-defined 24 bits to be placed into the
* packets (bits 8-31).
* \param[in] function_id Function id (8 bit registration ID) of the
* function to receive control on this
* local node to process packets for this
* message.
* \param[in] inj_ctr_grp_id Injection counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] inj_ctr_id Injection counter ID (within the inj counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] send_offset Offset of the send payload from the pa_base
* associated with the specified injection
* counter.
* \param[in] msg_len Total message length (in bytes).
*
* \retval 0 Success
* \retval non-zero Failure
*
* \note By default, the packet size is set to the largest value consistent
* with the message size. For example,
* - if msg_len >= 209, there will be 8 32-byte chunks in each packet,
* with the possible exception of the last packet, which could contain
* fewer chunks (209... of payload + 16 header).
* - if 177 <= msg_len < 208, there will be 7 chunks in the packet, etc.
*
* \note By default, for direct-put DMA messages, the pid0 and pid1 bits in the
* torus hardware packet header are determined by the recv_fifo_grp_id:
* - if recv_fifo_grp_id = 0 => (pid0,pid1) = (0,0)
* - if recv_fifo_grp_id = 1 => (pid0,pid1) = (0,1)
* - if recv_fifo_grp_id = 2 => (pid0,pid1) = (1,0)
* - if recv_fifo_grp_id = 3 => (pid0,pid1) = (1,1)
*/
int DMA_LocalMemFifoDescriptor(
DMA_InjDescriptor_t *desc,
unsigned int recv_fifo_grp_id,
unsigned int sw_arg,
unsigned int function_id,
unsigned int inj_ctr_grp_id,
unsigned int inj_ctr_id,
unsigned int send_offset,
unsigned int msg_len
);
/*!
* \brief Create a DMA Descriptor For a Torus Direct Put Broadcast Message
*
* A torus direct put broadcast message is one that is sent to all of the nodes
* in a specified direction along a specified line, its data
* is directly put into memory on the nodes along that line by the DMA on those
* nodes...it does not go into a reception fifo. Only one hint bit can be
* specified, dictating the direction (plus or minus) and line (x, y, or z).
*
* By default, the packet is included in the checksum. Retransmitted packets
* should not be included in the checksum.
*
* By default, the deterministic bubble normal virtual channel is used.
*
* A torus direct-put broadcast DMA descriptor contains the following:
*
* - 16 bytes of control information:
* - prefetch_only = 0
* - local_memcopy = 0
* - idma_counterId = Injection counter ID associated with the data being
* sent. This counter contains the base address of the
* message and the message length. Set based on caller's
* inj_ctr_grp_id and inj_ctr_id.
* - base_offset = Message offset (from the injection counter's base
* address). Set to caller's send_offset.
* - msg_length = Message length. Set to caller's msg_len.
*
* - 8 byte torus hardware header
* - CSum_Skip = DMA_CSUM_SKIP.
* - Sk = DMA_CSUM_BIT.
* - Hint = Set to caller's "hints".
* - Pid0, Pid1 = Set based on caller's "recv_ctr_grp_id" (see note).
* - Chunks = Set to largest size consistent with msg_len.
* - Dm = 1 (Indicates a direct-put packet).
* - Dynamic = 0 (Deterministic).
* - VC = Virtual Channel: Deterministic Bubble Normal.
* - X,Y,Z = Set according to the hints:
* Two of the directions are set to this node's
* coordinates (no movement in those directions).
* One direction is set to the dest specified
* by the caller.
*
* - 8 byte software header (initial values used by iDMA).
* - Put_Offset = Destination message offset (from the reception
* counter's base address). Set to caller's recv_offset.
* - rDMA_Counter = Reception counter ID. This counter is located on the
* destination node and contains the base address of the
* message and the message length. Set based on caller's
* recv_ctr_grp_id and recv_ctr_id.
* - Payload_Bytes = Number of valid bytes in the payload. Set by iDMA.
* - Flags = Pacing = 0.
* Remote-Get = 0.
* - iDMA_Fifo_ID = 0 (not used).
* - Func_Id = 0 (not used).
*
* This function creates the above descriptor.
*
* \param[in,out] desc Pointer to the storage where the descriptor
* will be created.
* \param[in] dest The final torus destination coordinate
* along the line specified by the hints.
* Should not exceed the number of nodes in
* the direction of travel.
* \param[in] hints Hint bits for torus routing (6 bits).
* Each bit corresponds to x+, x-, y+, y-,
* z+, z-. If a bit is set, it indicates that
* the packet wants to travel along the
* corresponding direction. If all bits are
* zero, the hardware calculates the hint bits.
* Only one bit may be specified.
* \param[in] inj_ctr_grp_id Injection counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] inj_ctr_id Injection counter ID (within the inj counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] send_offset Offset of the send payload from the pa_base
* associated with the specified injection
* counter.
* \param[in] recv_ctr_grp_id Reception counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] recv_ctr_id Reception counter ID (within the recv counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] recv_offset Offset of the payload from the pa_base
* associated with the specified reception
* counter.
* \param[in] msg_len Total message length (in bytes).
*
* \retval 0 Success
* \retval non-zero Failure
*
* \note By default, all payload bytes are included in the torus injection
* checksum. In the first byte of the torus hardware packet header,
* this corresponds to setting CSum_Skip = 0x8 (16 bytes) and Sk=0.
* The defaults can be changed by changing DMA_CSUM_SKIP and
* DMA_CSUM_BIT in this include file.
*
* \note By default, the packet size is set to the largest value consistent
* with the message size. For example,
* - if msg_len >= 209, there will be 8 32-byte chunks in each packet,
* with the possible exception of the last packet, which could contain
* fewer chunks (209... of payload + 16 header).
* - if 177 <= msg_len < 208, there will be 7 chunks in the packet, etc.
*
* \note By default, for direct-put DMA messages, the pid0 and pid1 bits in the
* torus hardware packet header are determined by the recv_ctr_grp_id:
* - if recv_ctr_grp_id = 0 => (pid0,pid1) = (0,0)
* - if recv_ctr_grp_id = 1 => (pid0,pid1) = (0,1)
* - if recv_ctr_grp_id = 2 => (pid0,pid1) = (1,0)
* - if recv_ctr_grp_id = 3 => (pid0,pid1) = (1,1)
* Pid0 determines into which physical torus fifo group on the destination
* node the packet is put, prior to the dma receiving it. Other than that,
* the only use for the pid bits is for debug, ie, if headers are being
* saved.
*/
int DMA_TorusDirectPutBcastDescriptor(
DMA_InjDescriptor_t *desc,
unsigned int dest,
unsigned int hints,
unsigned int inj_ctr_grp_id,
unsigned int inj_ctr_id,
unsigned int send_offset,
unsigned int recv_ctr_grp_id,
unsigned int recv_ctr_id,
unsigned int recv_offset,
unsigned int msg_len
);
/*!
* \brief Create a DMA Descriptor For a Torus Memory Fifo Broadcast Message
*
* A torus memory fifo broadcast message is one that is sent to all of the nodes
* in a specified direction along a specified line, its data is
* put into a reception memory fifo by the DMA on the destination nodes along
* that line. Only one hint bit can be specified, dictating the direction
* (plus or minus) and line (x, y, or z).
*
* By default, the packet is included in the checksum. Retransmitted packets
* should not be included in the checksum.
*
* By default, the deterministic bubble normal virtual channel is used.
*
* A torus memory fifo broadcast DMA descriptor contains the following:
*
* - 16 bytes of control information:
* - prefetch_only = 0
* - local_memcopy = 0
* - idma_counterId = Injection counter ID associated with the data being
* sent. This counter contains the base address of the
* message and the message length. Set based on caller's
* inj_ctr_grp_id and inj_ctr_id.
* - base_offset = Message offset (from the injection counter's base
* address). Set to caller's send_offset.
* - msg_length = Message length. Set to caller's msg_len.
*
* - 8 byte torus hardware header
* - CSum_Skip = DMA_CSUM_SKIP.
* - Sk = DMA_CSUM_BIT.
* - Hint = Set to caller's "hints".
* - Pid0, Pid1 = Set based on caller's "recv_fifo_grp_id" (see note).
* - Chunks = Set to largest size consistent with msg_len.
* - Dm = 0 (Indicates a memory fifo packet).
* - Dynamic = 0 (Deterministic).
* - VC = Virtual Channel: Deterministic Bubble Normal.
* - X,Y,Z = Set according to the hints:
* Two of the directions are set to this node's
* coordinates (no movement in those directions).
* One direction is set to the dest specified
* by the caller.
*
* - 8 byte software header (initial values used by iDMA).
* - Put_Offset = 0 (not used).
* - rDMA_Counter = 0 (not used).
* - Payload_Bytes = 0 (not used).
* - Flags = Pacing = 0.
* Remote-Get = 0.
* - iDMA_Fifo_ID = 0 (not used).
* - SW_Arg = User-defined 24 bits. Set to caller's sw_arg.
* - Func_Id = The registration ID of a function to receive control
* on the destination node to process the packet.
* Set to caller's function_id.
*
* This function creates the above descriptor.
*
* \param[in,out] desc Pointer to the storage where the descriptor
* will be created.
* \param[in] dest The final torus destination coordinate
* along the line specified by the hints.
* Should not exceed the number of nodes in
* the direction of travel.
* \param[in] recv_fifo_grp_id Reception fifo group ID
* (0 to DMA_NUM_REC_FIFO_GROUPS-1).
* \param[in] hints Hint bits for torus routing (6 bits).
* Each bit corresponds to x+, x-, y+, y-,
* z+, z-. If a bit is set, it indicates that
* the packet wants to travel along the
* corresponding direction. If all bits are
* zero, the hardware calculates the hint bits.
* Only one bit may be specified.
* \param[in] sw_arg User-defined 24 bits to be placed into the
* packets (bits 8-31).
* \param[in] function_id Function id (8 bit registration ID) of the
* function to receive control on the
* destination node to process packets for this
* message.
* \param[in] inj_ctr_grp_id Injection counter group ID
* (0 to DMA_NUM_COUNTER_GROUPS-1).
* \param[in] inj_ctr_id Injection counter ID (within the inj counter
* group) (0 to DMA_NUM_COUNTERS_PER_GROUP-1).
* \param[in] send_offset Offset of the send payload from the pa_base
* associated with the specified injection
* counter.
* \param[in] msg_len Total message length (in bytes).
*
* \retval 0 Success
* \retval non-zero Failure
*
* \note By default, all payload bytes are included in the torus injection
* checksum. In the first byte of the torus hardware packet header,
* this corresponds to setting CSum_Skip = 0x8 (16 bytes) and Sk=0.
* The defaults can be changed by changing DMA_CSUM_SKIP and
* DMA_CSUM_BIT in this include file.
*
* \note By default, the packet size is set to the largest value consistent
* with the message size. For example,
* - if msg_len >= 209, there will be 8 32-byte chunks in each packet,
* with the possible exception of the last packet, which could contain
* fewer chunks (209... of payload + 16 header).
* - if 177 <= msg_len < 208, there will be 7 chunks in the packet, etc.
*
* \note By default, for direct-put DMA messages, the pid0 and pid1 bits in the
* torus hardware packet header are determined by the recv_fifo_grp_id:
* - if recv_fifo_grp_id = 0 => (pid0,pid1) = (0,0)
* - if recv_fifo_grp_id = 1 => (pid0,pid1) = (0,1)
* - if recv_fifo_grp_id = 2 => (pid0,pid1) = (1,0)
* - if recv_fifo_grp_id = 3 => (pid0,pid1) = (1,1)
* Pid0 determines into which physical torus fifo group on the destination
* node the packet is put, prior to the dma receiving it. Other than that,
* the only use for the pid bits is for debug, ie, if headers are being
* saved.
*/
int DMA_TorusMemFifoBcastDescriptor(
DMA_InjDescriptor_t *desc,
unsigned int dest,
unsigned int recv_fifo_grp_id,
unsigned int hints,
unsigned int sw_arg,
unsigned int function_id,
unsigned int inj_ctr_grp_id,
unsigned int inj_ctr_id,
unsigned int send_offset,
unsigned int msg_len
);
/*!
* \brief Set or Change the Hint Bits in a Fifo Descriptor
*
* \param[in,out] desc Pointer to descriptor to be set or changed.
* \param[in] hints Hint bits to be set.
*
* \return None
*
*/
__INLINE__ void DMA_SetHints(
DMA_InjDescriptor_t *desc,
unsigned int hints
)
{
SPI_assert( desc != NULL );
desc->hwHdr.Hint = hints;
}
/*!
* \brief Set or Change the Virtual Channel and Dynamic Bit in a Descriptor
*
* \param[in,out] desc Pointer to descriptor to be set or changed.
* \param[in] vc Input virtual channel
* - 0 = Virtual channel dynamic 0
* - 1 = Virtual channel dynamic 1
* - 2 = Virtual channel deterministic bubble
* - 3 = Virtual channel deterministic priority
*
* \return None
*
* \post The Dynamic bit is set according to the specified virtual channel.
*
*/
__INLINE__ void DMA_SetVc(
DMA_InjDescriptor_t *desc,
unsigned int vc
)
{
SPI_assert( desc != NULL );
switch(vc) {
case DMA_PACKET_VC_D0:
case DMA_PACKET_VC_D1:
desc->hwHdr.Dynamic =1;
break;
case DMA_PACKET_VC_BN:
case DMA_PACKET_VC_BP:
desc->hwHdr.Dynamic =0;
break;
default:
SPI_assert(0);
}
desc->hwHdr.VC = vc;
}
/*!
* \brief Set Descriptor Pid Bits
*
* Given a pointer to the descriptor and the receive-side counter group number,
* set the Pid0 and Pid1 bits in the torus hardware header portion of the
* descriptor.
*
* \param[in] desc Pointer to injection descriptor
* \param[in] g Reception-side counter group number
* (0 through DMA_NUM_COUNTER_GROUPS).
*
* \return None
*
*/
__INLINE__ void DMA_SetDescriptorPids(
DMA_InjDescriptor_t *desc,
unsigned int g
)
{
/* Set the pid bits according to the group id g */
desc->hwHdr.Pid0 = _GN(g,30);
desc->hwHdr.Pid1 = _GN(g,31);
/* ---------------------------------
The above code performs the following:
switch(g) {
case 0:
desc->hwHdr.Pid0 = 0;
desc->hwHdr.Pid1 = 0;
break;
case 1
desc->hwHdr.Pid0 = 0;
desc->hwHdr.Pid1 = 1;
break;
case 2
desc->hwHdr.Pid0 = 1;
desc->hwHdr.Pid1 = 0;
break;
case 3
desc->hwHdr.Pid0 = 1;
desc->hwHdr.Pid1 = 1;
break;
default:
SPI_assert(0);
}
--------------------------------- */
}
/*!
* \brief Set or Change the Number of Chunks in a Fifo Descriptor
*
* \param[in,out] desc Pointer to the descriptor to be set or
* changed.
* \param[in] packet_chunks Number of 32B chunks in the packet
* (1 through 8).
*
* \return None
*
*/
__INLINE__ void DMA_SetChunks(
DMA_InjDescriptor_t *desc,
unsigned int packet_chunks
)
{
SPI_assert( desc != NULL );
SPI_assert( packet_chunks >=1);
SPI_assert( packet_chunks <=8);
desc->hwHdr.Chunks = (packet_chunks-1) ;
}
/*!
* \brief Set or Change the Message Length in a Fifo Descriptor
*
* \param[in,out] desc Pointer to the descriptor to be set or changed.
* \param[in] msg_len Number of bytes in the payload of the message.
*
* \return None
*
*/
__INLINE__ void DMA_SetMessageLength(
DMA_InjDescriptor_t *desc,
unsigned int msg_len
)
{
SPI_assert( desc != NULL );
desc->msg_length= msg_len;
}
/*!
* \brief Change the Checksum Characteristics in a Fifo Descriptor
*
* \param[in,out] desc Pointer to the descriptor to be changed.
* \param[in] csum_skip The number of 2-bytes to skip in the checksum
* (7 bits).
* \param[in] skip The checksum skip attribute:
* 0 = The packets participates in the injection
* checksum.
* 1 = The packet does not participate in the
* injection checksum.
*
* \return None
*
*/
__INLINE__ void DMA_SetInjCsum(
DMA_InjDescriptor_t *desc,
unsigned int csum_skip,
unsigned int skip
)
{
SPI_assert( desc != NULL );
SPI_assert( skip <=1 );
desc->hwHdr.CSum_Skip = csum_skip;
desc->hwHdr.Sk = skip;
}
/*!
* \brief Determine the Number of Packet Chunks for the First Packet of a
* Message
*
* Compute the best (largest) packet size in units of 32B chunks given the
* message length.
*
* \param[in] msg_len Message length
*
* \retval numPacketChunks Number of 32B chunks needed in the first packet
* of a message whose length is msg_len.
* This will be a number from 1 through 8.
* \retval 0 This is considered an error, resulting from a
* msg_len = 0. The DMA must send at least 1 byte.
*/
__INLINE__ int DMA_PacketChunks(
unsigned msg_len
)
{
/* Do most common case first */
if (msg_len > 208) return 8;
/* Error case...the DMA must send at least one byte of data */
SPI_assert( msg_len > 0);
/* Basically add in the packet header and round to 32B multiple */
{
int chunks = ( msg_len - 1 + sizeof(DMA_PacketHeader_t) ) / 32;
return (1+chunks);
}
}
/*!
* \brief Zero Out All Fields a Descriptor
*
* \param[in] desc Pointer to descriptor to be zero'd.
*
* \post The descriptor is zero'd.
*
*/
__INLINE__ void DMA_ZeroOutDescriptor(
DMA_InjDescriptor_t *desc
)
{
/*
* Possible optimizations:
* There are 32 bytes in the descriptor and it should be L1 aligned.
* SPI_assert(( desc & 0x000000FF) == 0); // check alignment, not needed if can't
* // easily use double hummer.
* _bgp_dcache_zero_line(desc); //Not allowed with SWOA
* Should be a better way to do this.
*/
SPI_assert( desc != NULL );
{
int *addr = (int *) desc ;
/* Generates 8 stw's */
addr[0] = 0;
addr[1] = 0;
addr[2] = 0;
addr[3] = 0;
addr[4] = 0;
addr[5] = 0;
addr[6] = 0;
addr[7] = 0;
}
}
/*!
* \brief Update the Offset and Length in a Descriptor
*
* \param[in] desc Pointer to descriptor to be updated.
* \param[in] offset The new offset value.
* \param[in] length The new length value.
*
* \post The descriptor is updated.
*
*/
__INLINE__ void DMA_DescriptorUpdateOffsetLength (DMA_InjDescriptor_t *desc,
unsigned offset,
unsigned length)
{
desc->base_offset = offset;
desc->msg_length = length;
}
/*!
* \brief Set the Put Offset in a Descriptor
*
* This sets the "put_offset" field of the software packet header in the
* provided descriptor. This field is placed into the packet header by
* the DMA. In the first packet, this field is placed into the packet
* unchanged. In each subsequent packet, the DMA adds to this field
* the number of payload bytes from the previous packet.
*
* \param[in] desc Pointer to descriptor.
* \param[in] offset The offset value to be set.
*
* \post The Put Offset in the descriptor is set.
*
*/
__INLINE__ void DMA_DescriptorSetPutOffset (DMA_InjDescriptor_t *desc,
unsigned offset)
{
desc->hwHdr.Put_Offset = offset;
}
__END_DECLS
#endif