Software APIs
dif_dma.h
Go to the documentation of this file.
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_DMA_H_
6#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_DMA_H_
7
8/**
9 * @file
10 * @brief <a href="/hw/ip/dma/doc/">DMA Controller</a> Device Interface
11 * Functions
12 */
13
14#include <stdint.h>
15
16#include "dma_regs.h" // Generated.
18
19#ifdef __cplusplus
20extern "C" {
21#endif // __cplusplus
22
23// Target Address space that the source address pointer refers to.
24typedef enum dif_dma_address_space_id {
25 /* OpenTitan 32 bit internal bus. */
26 kDifDmaOpentitanInternalBus = 0x07,
27
28 /* SoC control register address bus using 32 bit (or 64 bits if configured by
29 an SoC) CTN port .*/
30 kDifDmaSoCControlRegisterBus = 0x0a,
31
32 /* SoC system address bus using 64 bit SYS port. */
33 kDifDmaSoCSystemBus = 0x09,
34} dif_dma_address_space_id_t;
35
36/* Supported transaction widths by the DMA */
37typedef enum dif_dma_transaction_width {
38 /* Transfer 1 byte at a time.*/
39 kDifDmaTransWidth1Byte = 0x00,
40 /* Transfer 2 byte at a time.*/
41 kDifDmaTransWidth2Bytes = 0x01,
42 /* Transfer 4 byte at a time.*/
43 kDifDmaTransWidth4Bytes = 0x02,
44} dif_dma_transaction_width_t;
45
46/* Supported Opcodes by the DMA */
47typedef enum dif_dma_transaction_opcode {
48 /* Simple copy from source to destination.*/
49 kDifDmaCopyOpcode = 0x00,
50 /* Inline hashing with SHA2-256.*/
51 kDifDmaSha256Opcode = 0x01,
52 /* Inline hashing with SHA2-384.*/
53 kDifDmaSha384Opcode = 0x02,
54 /* Inline hashing with SHA2-512.*/
55 kDifDmaSha512Opcode = 0x03,
56} dif_dma_transaction_opcode_t;
57
58/**
59 * Define the transaction address space.
60 */
62 uint64_t address;
63 dif_dma_address_space_id_t asid;
65
66/**
67 * Addressing configuration.
68 */
69typedef struct dif_dma_address_config {
70 /* Address wraps after each chunk, so chunks overlap */
71 bool wrap;
72 /* Increment after each (partial-)word transfer */
73 bool increment;
75
76/**
77 * Parameters for a DMA Controller transaction.
78 */
79typedef struct dif_dma_transaction {
82 dif_dma_address_config_t src_config;
83 dif_dma_address_config_t dst_config;
84 /* Chunk size (in bytes) of the data object to transferred.*/
85 size_t chunk_size;
86 /* Total size (in bytes) of the data object to transferred.*/
87 size_t total_size;
88 /* Iteration width.*/
89 dif_dma_transaction_width_t width;
91
92/**
93 * Configures DMA Controller for a transaction.
94 *
95 * This function should be called every time before `dif_dma_start`.
96 *
97 * @param dma A DMA Controller handle.
98 * @param config Transaction configuration parameters.
99 * @return The result of the operation.
100 */
103 dif_dma_transaction_t transaction);
104
105/**
106 * Configures DMA Controller hardware handshake mode.
107 *
108 * This function should be called before `dif_dma_start`.
109 *
110 * Hardware handshake mode is used to push / pop FIFOs to / from low speed IO
111 * peripherals receiving data e.g. I3C receive buffer.
112 *
113 * @param dma A DMA Controller handle.
114 * @return The result of the operation.
115 */
118
119/**
120 * Disable DMA Controller hardware handshake mode.
121 *
122 * @param dma A DMA Controller handle.
123 * @return The result of the operation.
124 */
127
128/**
129 * Begins a DMA Controller transaction.
130 *
131 * Before this function the DMA transaction shall be configured by calling the
132 * function `dif_dma_configure` and optionally `dif_dma_handshake_enable` can be
133 * called.
134 *
135 * @param dma A DMA Controller handle.
136 * @param opcode Transaction opcode.
137 * @return The result of the operation.
138 */
141 dif_dma_transaction_opcode_t opcode);
142
143/**
144 * Abort the DMA Controller transaction in execution.
145 *
146 * @param dma A DMA Controller handle.
147 * @return The result of the operation.
148 */
151
152/**
153 * Set the DMA enabled memory range within the OT internal memory space.
154 *
155 * @param dma A DMA Controller handle.
156 * @param address Base address.
157 * @param size The range size.
158 * @return The result of the operation.
159 */
161dif_result_t dif_dma_memory_range_set(const dif_dma_t *dma, uint32_t address,
162 size_t size);
163
164/**
165 * Get the DMA enabled memory range within the OT internal memory space.
166 *
167 * @param dma A DMA Controller handle.
168 * @param[out] address Out-param for the base address.
169 * @param[out] size Out-param for the range size.
170 * @return The result of the operation.
171 */
173dif_result_t dif_dma_memory_range_get(const dif_dma_t *dma, uint32_t *address,
174 size_t *size);
175/**
176 * Locks out the DMA memory range register.
177 *
178 * This function is reentrant: calling it while functionality is locked will
179 * have no effect and return `kDifOk`.
180 *
181 * @param dma A DMA Controller handle.
182 * @return The result of the operation.
183 */
186
187/**
188 * Checks whether the DMA memory range is locked.
189 *
190 * @param dma A DMA Controller handle.
191 * @param[out] is_locked Out-param for the locked state.
192 * @return The result of the operation.
193 */
196 bool *is_locked);
197
198/**
199 * Checks whether the DMA memory range is valid.
200 *
201 * @param dma A DMA Controller handle.
202 * @param[out] is_valid Out-param for the valid state.
203 * @return The result of the operation.
204 */
207 bool *is_valid);
208
209typedef enum dif_dma_status_code {
210 // DMA operation is active.
211 kDifDmaStatusBusy = 0x01 << DMA_STATUS_BUSY_BIT,
212 // Configured DMA operation is complete.
213 kDifDmaStatusDone = 0x01 << DMA_STATUS_DONE_BIT,
214 // Set once aborted operation drains.
215 kDifDmaStatusAborted = 0x01 << DMA_STATUS_ABORTED_BIT,
216 // Error occurred during the operation.
217 // Check the error_code for information about the source of the error.
218 kDifDmaStatusError = 0x01 << DMA_STATUS_ERROR_BIT,
219 // Set once the SHA2 digest is valid after finishing a transfer
220 kDifDmaStatusSha2DigestValid = 0x01 << DMA_STATUS_SHA2_DIGEST_VALID_BIT,
221 // Transfer of a single chunk is complete.
222 kDifDmaStatusChunkDone = 0x01 << DMA_STATUS_CHUNK_DONE_BIT,
223} dif_dma_status_code_t;
224
225/**
226 * Bitmask with the `dif_dma_status_code_t` values.
227 */
228typedef uint32_t dif_dma_status_t;
229
230/**
231 * Reads the DMA status.
232 *
233 * @param dma A DMA Controller handle.
234 * @param[out] status Out-param for the status.
235 * @return The result of the operation.
236 */
239
240/**
241 * Writes the DMA status register and clears the corrsponding status bits.
242 *
243 * @param dma A DMA Controller handle.
244 * @param status Status bits to be cleared.
245 * @return The result of the operation.
246 */
250
251/**
252 * Clear all status bits of the status register.
253 *
254 * @param dma A DMA Controller handle.
255 * @return The result of the operation.
256 */
259
260/**
261 * Poll the DMA status util a given flag in the register is set.
262 *
263 * @param dma A DMA Controller handle.
264 * @param flag The status that needs to bet set.
265 * @return The result of the operation.
266 */
269 dif_dma_status_code_t flag);
270
271typedef enum dif_dma_error_code {
272 // Source address error.
273 kDifDmaErrorNone = 0x00,
274 // Source address error.
275 kDifDmaErrorSourceAddress = 0x01 << 0,
276 // Destination address error.
277 kDifDmaErrorDestinationAddress = 0x01 << 1,
278 // Opcode error.
279 kDifDmaErrorOpcode = 0x01 << 2,
280 // Size error.
281 kDifDmaErrorSize = 0x01 << 3,
282 // Bus transaction error.
283 kDifDmaErrorBus = 0x01 << 4,
284 // DMA enable memory config error.
285 kDifDmaErrorEnableMemoryConfig = 0x01 << 5,
286 // Register range valid error.
287 kDifDmaErrorRangeValid = 0x01 << 6,
288 // Invalid ASID error.
289 kDifDmaErrorInvalidAsid = 0x01 << 7,
290} dif_dma_error_code_t;
291
292/**
293 * Reads the DMA error code.
294 *
295 * @param dma A DMA Controller handle.
296 * @param[out] error Out-param for the error code.
297 * @return The result of the operation.
298 */
301 dif_dma_error_code_t *error);
302
303/**
304 * Return the digest length given a DMA opcode.
305 *
306 * @param opcode A DMA opcode.
307 * @param digest_len The digest length.
308 * @return The result of the operation.
309 */
310dif_result_t dif_dma_get_digest_length(dif_dma_transaction_opcode_t opcode,
311 uint32_t *digest_len);
312
313/**
314 * Read out the SHA2 digest
315 *
316 * @param dma A DMA Controller handle.
317 * @param opcode The opcode to select the length of the read digest.
318 * @param[out] digest Pointer to the digest, to store the read values.
319 * @return The result of the operation.
320 */
322 dif_dma_transaction_opcode_t opcode,
323 uint32_t digest[]);
324
325/**
326 * Enable DMA controller handshake interrupt.
327 *
328 * @param dma A DMA Controller handle.
329 * @param enable_state Enable state. The bit position corresponds to the IRQ
330 * index.
331 * @return The result of the operation.
332 */
335 uint32_t enable_state);
336
337/**
338 * Enable the corresponding DME handshake interrupt clearing mechanism.
339 *
340 * @param dma A DMA Controller handle.
341 * @param clear_state Enable interrupt clearing mechanism. The bit position
342 * corresponds to the IRQ index.
343 * @return The result of the operation.
344 */
347 uint32_t clear_state);
348
349/**
350 * Select the bus interface for the interrupt clearing mechanism.
351 * 0: CTN/System fabric
352 * 1: OT-internal crossbar
353 *
354 * @param dma A DMA Controller handle.
355 * @param clear_irq_bus Bus selection for the clearing mechanism. The bit
356 * position corresponds to the IRQ index.
357 * @return The result of the operation.
358 */
361 uint32_t clear_irq_bus);
362
363/**
364 * Address index for every interrupt. Used to configure the write address and
365 * write value for the interrupt clearing mechanism.
366 */
367typedef enum dif_dma_intr_idx {
368 kDifDmaIntrClearIdx0 = 0x0,
369 kDifDmaIntrClearIdx1 = 0x4,
370 kDifDmaIntrClearIdx2 = 0x8,
371 kDifDmaIntrClearIdx3 = 0xC,
372 kDifDmaIntrClearIdx4 = 0x10,
373 kDifDmaIntrClearIdx5 = 0x14,
374 kDifDmaIntrClearIdx6 = 0x18,
375 kDifDmaIntrClearIdx7 = 0x1C,
376 kDifDmaIntrClearIdx8 = 0x20,
377 kDifDmaIntrClearIdx9 = 0x24,
378 kDifDmaIntrClearIdx10 = 0x28,
380
381/**
382 * Set the write address for the interrupt clearing mechanism.
383 *
384 * @param dma A DMA Controller handle.
385 * @param idx Index of the selected interrupt.
386 * @param intr_src_addr Address to write the interrupt clearing value to.
387 * @return The result of the operation.
388 */
391 uint32_t intr_src_addr);
392
393/**
394 * Set the write value for the interrupt clearing mechanism.
395 *
396 * @param dma A DMA Controller handle.
397 * @param idx Index of the selected interrupt.
398 * @param intr_src_value Value to write the interrupt clearing value to.
399 * @return The result of the operation.
400 */
404 uint32_t intr_src_value);
405
406#ifdef __cplusplus
407} // extern "C"
408#endif // __cplusplus
409
410#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_DMA_H_