1/* 2 * Copyright (c) 2014, ETH Zurich. All rights reserved. 3 * 4 * This file is distributed under the terms in the attached LICENSE file. 5 * If you do not find this file, copies can be found by writing to: 6 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group. 7 */ 8 9#include <string.h> 10#include <barrelfish/barrelfish.h> 11#include <xeon_phi/xeon_phi.h> 12#include <dev/xeon_phi/xeon_phi_dma_dev.h> 13 14#include <dma_mem_utils.h> 15 16#include <xeon_phi/xeon_phi_dma_internal.h> 17#include <xeon_phi/xeon_phi_dma_descriptors_internal.h> 18 19#include <debug.h> 20 21#define ASSERT_ALIGNED(x) \ 22 assert((x) && ((((uintptr_t)x) & (XEON_PHI_DMA_ALIGNMENT - 1)) == 0)) 23 24static inline void clear_descriptor(void *descriptor) 25{ 26 uint64_t *desc = descriptor; 27 desc[0] = 0; 28 desc[1] = 0; 29} 30 31/* 32 * ============================================================================ 33 * Public Interface 34 * ============================================================================ 35 */ 36 37/** 38 * \brief initializes the hardware specific part of the descriptor to be used 39 * for memcpy descriptors 40 * 41 * \param desc Xeon Phi descriptor 42 * \param src Source address of the transfer 43 * \param dst destination address of the transfer 44 * \param size number of bytes to copy 45 * \param flags control flags 46 * 47 * XXX: this function assumes that the size of the descriptor has already been 48 * checked and must match the maximum transfer size of the channel 49 */ 50inline void xeon_phi_dma_desc_fill_memcpy(struct dma_descriptor *desc, 51 lpaddr_t src, 52 lpaddr_t dst, 53 uint32_t size, 54 uint32_t flags) 55{ 56 uint8_t *d = dma_desc_get_desc_handle(desc); 57 58 clear_descriptor(d); 59 60 ASSERT_ALIGNED(src); 61 ASSERT_ALIGNED(dst); 62 ASSERT_ALIGNED(size); 63 64 if (flags & XEON_PHI_DMA_DESC_FLAG_INTR) { 65 xeon_phi_dma_desc_memcpy_intr_insert(d, 0x1); 66 } 67 if (flags & XEON_PHI_DMA_DESC_FLAG_TWB) { 68 xeon_phi_dma_desc_memcpy_twb_insert(d, 0x1); 69 } 70 if (flags & XEON_PHI_DMA_DESC_FLAG_C) { 71 xeon_phi_dma_desc_memcpy_c_insert(d, 0x1); 72 } 73 if (flags & XEON_PHI_DMA_DESC_FLAG_CO) { 74 xeon_phi_dma_desc_memcpy_co_insert(d, 0x1); 75 } 76 if (flags & XEON_PHI_DMA_DESC_FLAG_ECY) { 77 xeon_phi_dma_desc_memcpy_ecy_insert(d, 0x1); 78 } 79 80 xeon_phi_dma_desc_memcpy_src_insert(d, src); 81 xeon_phi_dma_desc_memcpy_dst_insert(d, dst); 82 xeon_phi_dma_desc_memcpy_length_insert(d, (size >> XEON_PHI_DMA_ALIGN_SHIFT)); 83 xeon_phi_dma_desc_memcpy_dtype_insert(d, xeon_phi_dma_desc_memcpy); 84 85} 86 87/** 88 * \brief initializes the hardware specific part of the descriptor to be used 89 * for nop descriptors (null descriptors) 90 * 91 * \param desc Xeon Phi descriptor 92 */ 93inline void xeon_phi_dma_desc_fill_nop(struct dma_descriptor *desc) 94{ 95 clear_descriptor(dma_desc_get_desc_handle(desc)); 96} 97 98/** 99 * \brief initializes the hardware specific part of the descriptor to be used 100 * for general descriptors 101 * 102 * \param desc Xeon Phi descriptor 103 * \param dst destination address 104 * \param data Data payload for the request (request specific) 105 */ 106inline void xeon_phi_dma_desc_fill_general(struct dma_descriptor *desc, 107 lpaddr_t dst, 108 uint64_t data) 109{ 110 uint8_t *d = dma_desc_get_desc_handle(desc); 111 112 clear_descriptor(d); 113 114 ASSERT_ALIGNED(dst); 115 116 xeon_phi_dma_desc_general_data_insert(d, data); 117 xeon_phi_dma_desc_general_dst_insert(d, dst); 118 119 xeon_phi_dma_desc_general_dtype_insert(d, 120 xeon_phi_dma_desc_general); 121} 122 123/** 124 * \brief initializes the hardware specific part of the descriptor to be used 125 * for status descriptors 126 * 127 * \param desc Xeon Phi descriptor 128 * \param dst destination address 129 * \param data Data payload for the request (request specific) 130 * \param flags Descriptor flags 131 */ 132inline void xeon_phi_dma_desc_fill_status(struct dma_descriptor *desc, 133 lpaddr_t dst, 134 uint64_t data, 135 uint32_t flags) 136{ 137 uint8_t *d = dma_desc_get_desc_handle(desc); 138 139 clear_descriptor(d); 140 141 ASSERT_ALIGNED(dst); 142 143 xeon_phi_dma_desc_status_data_insert(d, data); 144 xeon_phi_dma_desc_status_dst_insert(d, dst); 145 if (flags & XEON_PHI_DMA_DESC_FLAG_INTR) { 146 xeon_phi_dma_desc_status_intr_insert(d, 0x1); 147 } 148 149 xeon_phi_dma_desc_status_dtype_insert(d, 150 xeon_phi_dma_desc_status); 151} 152