1 /* 2 * Copyright (c) 2021-2023, The TrustedFirmware-M Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #ifndef CC3XX_DMA_H 9 #define CC3XX_DMA_H 10 11 #include "cc3xx_error.h" 12 #include "cc3xx_config.h" 13 14 #include <stdint.h> 15 #include <stddef.h> 16 #include <string.h> 17 #include <stdbool.h> 18 19 #define CC3XX_DMA_BLOCK_BUF_MAX_SIZE 64 20 21 struct cc3xx_dma_state_t { 22 uint8_t block_buf[CC3XX_DMA_BLOCK_BUF_MAX_SIZE]; 23 size_t block_buf_size_in_use; 24 size_t block_buf_size; 25 bool block_buf_needs_output; 26 uintptr_t output_addr; 27 size_t output_size; 28 uint32_t remap_cpusel; 29 size_t current_bytes_output; 30 }; 31 32 extern struct cc3xx_dma_state_t dma_state; 33 34 #ifdef CC3XX_CONFIG_DMA_REMAP_ENABLE 35 36 typedef struct { 37 uintptr_t region_base; /*!< The base of the region that will be remapped */ 38 size_t region_size; /*!< The size of the region that will be remapped */ 39 uintptr_t remap_base; /*!< The base of the region that mapped to */ 40 size_t remap_cpusel_offset; /*!< How much the remap will be incremented per cpu */ 41 } cc3xx_dma_remap_region_t; 42 43 #endif /* CC3XX_CONFIG_DMA_REMAP_ENABLE */ 44 45 #ifdef __cplusplus 46 extern "C" { 47 #endif 48 49 #ifdef CC3XX_CONFIG_DMA_REMAP_ENABLE 50 51 /** 52 * @brief Configure and enable a remap region. Any DMA 53 * input/output address that is within a remap 54 * region will be altered to the offset into the 55 * region plus the remap base (plus an extra 56 * cpusel offset if configured). This is intended 57 * primarily to be used to remap CPU TCM accesses 58 * to use the TCM subordinate interface (as cc3xx 59 * has no access via the main TCM mapping). 60 61 * @param[in] remap_region_idx Which remap region should be configured and 62 * enabled. 63 * @param[in] remap_region_idx The configuration for the remap region. 64 * 65 * @return CC3XX_ERR_SUCCESS on success, another 66 * cc3xx_err_t on error. 67 */ 68 void cc3xx_lowlevel_dma_remap_region_init(uint32_t remap_region_idx, 69 cc3xx_dma_remap_region_t *region); 70 /** 71 * @brief Clear and disable a remap region. 72 * 73 * @param[in] remap_region_idx Which remap region should be cleared and 74 * disabled. 75 * 76 * @return CC3XX_ERR_SUCCESS on success, another 77 * cc3xx_err_t on error. 78 */ 79 void cc3xx_lowlevel_dma_remap_region_clear(uint32_t remap_region_idx); 80 81 /** 82 * @brief Select which CPU memory space should be used for remap 83 * offsets. Useful for selecting different ITCM / DTCMs. 84 * 85 * @param[in] cpuid Which CPU's memory space should be accessed when 86 * remapping. 87 * 88 * @return CC3XX_ERR_SUCCESS on success, another cc3xx_err_t on 89 * error. 90 */ 91 void cc3xx_lowlevel_dma_tcm_cpusel(uint32_t cpuid); 92 93 #endif /* CC3XX_CONFIG_DMA_REMAP_ENABLE */ 94 95 /** 96 * @brief Use the cc3xx DMA to copy data directly without performing 97 * cryptographic operations on it. This function can be used 98 * as a drop-in replacement for memcpy. 99 * 100 * @param[out] dest The pointer to copy data to. 101 * @param[in] src The pointer to copy data from. 102 * @param[in] length The size of the data. 103 */ 104 void cc3xx_lowlevel_dma_copy_data(void* dest, const void* src, size_t length); 105 106 /** 107 * @brief Set the DMA input location. This triggers DMA input to be 108 * started. This operation buffers data, and 109 * cc3xx_dma_flush_buffer must be called to ensure all data 110 * is processed. 111 * 112 * @param[in] buf The pointer to copy data from. 113 * @param[in] length The size of the data. 114 * @param[in] write_output Whether the data should be output from the engine. 115 * 116 * @return CC3XX_ERR_SUCCESS on success, another cc3xx_err_t on 117 * error. 118 */ 119 cc3xx_err_t cc3xx_lowlevel_dma_buffered_input_data(const void* buf, size_t length, 120 bool write_output); 121 122 /** 123 * @brief Flush the DMA buffer. Engine setup is not saved with the 124 * DMA buffer, so the engine must be configured correctly 125 * before this is called. 126 * 127 * @param[in] zero_pad_first Whether the data should be zero-padded to the DMA 128 * buffer size before being input. 129 */ 130 void cc3xx_lowlevel_dma_flush_buffer(bool zero_pad_first); 131 132 /** 133 * @brief Set the size of the DMA block buffer. This must be called 134 * before the DMA is used, as the default value is 0, which 135 * is invalid. 136 * 137 * @param[in] size The size of the block buffer. Must not be larger than 138 * CC3XX_DMA_BLOCK_BUF_MAX_SIZE. 139 */ 140 void cc3xx_lowlevel_dma_set_buffer_size(size_t size); 141 142 /** 143 * @brief Set the DMA output location. This controls where the 144 * DMA will output to after input is started. 145 * 146 * @param[out] buf The pointer to output to. 147 * @param[in] length The size of the output location. The DMA will not copy 148 * more data than this to the pointer. 149 */ 150 void cc3xx_lowlevel_dma_set_output(void* buf, size_t length); 151 152 /** 153 * @brief Uninitialize the DMA. 154 * 155 * @note The DMA is not implicitly uninitialized 156 * on an error. 157 * 158 */ 159 void cc3xx_lowlevel_dma_uninit(void); 160 161 #ifdef __cplusplus 162 } 163 #endif 164 165 #endif /* CC3XX_DMA_H */ 166