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
20 extern "C" {
21 #endif // __cplusplus
22 
23 // Target Address space that the source address pointer refers to.
24 typedef 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 */
37 typedef 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 */
47 typedef 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  * Parameters for a DMA Controller transaction.
68  */
69 typedef struct dif_dma_transaction {
72  /* Chunk size (in bytes) of the data object to transferred.*/
73  size_t chunk_size;
74  /* Total size (in bytes) of the data object to transferred.*/
75  size_t total_size;
76  /* Iteration width.*/
77  dif_dma_transaction_width_t width;
79 
80 /**
81  * Configures DMA Controller for a transaction.
82  *
83  * This function should be called every time before `dif_dma_start`.
84  *
85  * @param dma A DMA Controller handle.
86  * @param config Transaction configuration parameters.
87  * @return The result of the operation.
88  */
91  dif_dma_transaction_t transaction);
92 
93 /**
94  * Parameters for a handshake mode transaction.
95  */
96 typedef struct dif_dma_handshake {
97  /* Auto Increments the memory buffer address register by total data size to
98  * point to the next memory buffer address.*/
99  bool memory_auto_increment;
100 
101  /* If `true`, reads/writes from/to incremental addresses for FIFO data
102  * register addresses, otherwise uses the same address for subsequent
103  * transactions.*/
104  bool fifo_auto_increment;
105 
106  /* If `true` move data from memory buffer to the LSIO FIFO, otherwise move
107  * data from the LSIO FIFO to the memory buffer.*/
108  bool direction_from_mem_to_fifo;
110 
111 /**
112  * Configures DMA Controller hardware handshake mode.
113  *
114  * This function should be called before `dif_dma_start`.
115  *
116  * Hardware handshake mode is used to push / pop FIFOs to / from low speed IO
117  * peripherals receiving data e.g. I3C receive buffer.
118  *
119  * @param dma A DMA Controller handle.
120  * @param handshake Hardware handshake configuration parameters.
121  * @return The result of the operation.
122  */
125  dif_dma_handshake_t handshake);
126 
127 /**
128  * Disable DMA Controller hardware handshake mode.
129  *
130  * @param dma A DMA Controller handle.
131  * @return The result of the operation.
132  */
135 
136 /**
137  * Begins a DMA Controller transaction.
138  *
139  * Before this function the DMA transaction shall be configured by calling the
140  * function `dif_dma_configure` and optionally `dif_dma_handshake_enable` can be
141  * called.
142  *
143  * @param dma A DMA Controller handle.
144  * @param opcode Transaction opcode.
145  * @return The result of the operation.
146  */
149  dif_dma_transaction_opcode_t opcode);
150 
151 /**
152  * Abort the DMA Controller transaction in execution.
153  *
154  * @param dma A DMA Controller handle.
155  * @return The result of the operation.
156  */
159 
160 /**
161  * Set the DMA enabled memory range within the OT internal memory space.
162  *
163  * @param dma A DMA Controller handle.
164  * @param address Base address.
165  * @param size The range size.
166  * @return The result of the operation.
167  */
169 dif_result_t dif_dma_memory_range_set(const dif_dma_t *dma, uint32_t address,
170  size_t size);
171 
172 /**
173  * Get the DMA enabled memory range within the OT internal memory space.
174  *
175  * @param dma A DMA Controller handle.
176  * @param[out] address Out-param for the base address.
177  * @param[out] size Out-param for the range size.
178  * @return The result of the operation.
179  */
181 dif_result_t dif_dma_memory_range_get(const dif_dma_t *dma, uint32_t *address,
182  size_t *size);
183 /**
184  * Locks out the DMA memory range register.
185  *
186  * This function is reentrant: calling it while functionality is locked will
187  * have no effect and return `kDifOk`.
188  *
189  * @param dma A DMA Controller handle.
190  * @return The result of the operation.
191  */
194 
195 /**
196  * Checks whether the DMA memory range is locked.
197  *
198  * @param dma A DMA Controller handle.
199  * @param[out] is_locked Out-param for the locked state.
200  * @return The result of the operation.
201  */
204  bool *is_locked);
205 
206 /**
207  * Checks whether the DMA memory range is valid.
208  *
209  * @param dma A DMA Controller handle.
210  * @param[out] is_valid Out-param for the valid state.
211  * @return The result of the operation.
212  */
215  bool *is_valid);
216 
217 typedef enum dif_dma_status_code {
218  // DMA operation is active.
219  kDifDmaStatusBusy = 0x01 << DMA_STATUS_BUSY_BIT,
220  // Configured DMA operation is complete.
221  kDifDmaStatusDone = 0x01 << DMA_STATUS_DONE_BIT,
222  // Set once aborted operation drains.
223  kDifDmaStatusAborted = 0x01 << DMA_STATUS_ABORTED_BIT,
224  // Error occurred during the operation.
225  // Check the error_code for information about the source of the error.
226  kDifDmaStatusError = 0x01 << DMA_STATUS_ERROR_BIT,
227  // Set once the SHA2 digest is valid after finishing a transfer
228  kDifDmaStatusSha2DigestValid = 0x01 << DMA_STATUS_SHA2_DIGEST_VALID_BIT,
229 } dif_dma_status_code_t;
230 
231 /**
232  * Bitmask with the `dif_dma_status_code_t` values.
233  */
234 typedef uint32_t dif_dma_status_t;
235 /**
236  * Reads the DMA status.
237  *
238  * @param dma A DMA Controller handle.
239  * @param[out] status Out-param for the status.
240  * @return The result of the operation.
241  */
244 
245 /**
246  * Writes the DMA status register and clears the corrsponding status bits.
247  *
248  * @param dma A DMA Controller handle.
249  * @param status Status bits to be cleared.
250  * @return The result of the operation.
251  */
255 
256 /**
257  * Clear all status bits of the status register.
258  *
259  * @param dma A DMA Controller handle.
260  * @return The result of the operation.
261  */
264 
265 /**
266  * Poll the DMA status util a given flag in the register is set.
267  *
268  * @param dma A DMA Controller handle.
269  * @param flag The status that needs to bet set.
270  * @return The result of the operation.
271  */
274  dif_dma_status_code_t flag);
275 
276 typedef enum dif_dma_error_code {
277  // Source address error.
278  kDifDmaErrorNone = 0x00,
279  // Source address error.
280  kDifDmaErrorSourceAddress = 0x01 << 0,
281  // Destination address error.
282  kDifDmaErrorDestinationAddress = 0x01 << 1,
283  // Opcode error.
284  kDifDmaErrorOpcode = 0x01 << 2,
285  // Size error.
286  kDifDmaErrorSize = 0x01 << 3,
287  // Bus transaction error.
288  kDifDmaErrorBus = 0x01 << 4,
289  // DMA enable memory config error.
290  kDifDmaErrorEnableMemoryConfig = 0x01 << 5,
291  // Register range valid error.
292  kDifDmaErrorRangeValid = 0x01 << 6,
293  // Invalid ASID error.
294  kDifDmaErrorInvalidAsid = 0x01 << 7,
295 } dif_dma_error_code_t;
296 
297 /**
298  * Reads the DMA error code.
299  *
300  * @param dma A DMA Controller handle.
301  * @param[out] error Out-param for the error code.
302  * @return The result of the operation.
303  */
306  dif_dma_error_code_t *error);
307 
308 /**
309  * Return the digest length given a DMA opcode.
310  *
311  * @param opcode A DMA opcode.
312  * @param digest_len The digest length.
313  * @return The result of the operation.
314  */
315 dif_result_t dif_dma_get_digest_length(dif_dma_transaction_opcode_t opcode,
316  uint32_t *digest_len);
317 
318 /**
319  * Read out the SHA2 digest
320  *
321  * @param dma A DMA Controller handle.
322  * @param opcode The opcode to select the length of the read digest.
323  * @param[out] digest Pointer to the digest, to store the read values.
324  * @return The result of the operation.
325  */
327  dif_dma_transaction_opcode_t opcode,
328  uint32_t digest[]);
329 
330 /**
331  * Enable DMA controller handshake interrupt.
332  *
333  * @param dma A DMA Controller handle.
334  * @param enable_state Enable state. The bit position corresponds to the IRQ
335  * index.
336  * @return The result of the operation.
337  */
340  uint32_t enable_state);
341 
342 /**
343  * Enable the corresponding DME handshake interrupt clearing mechanism.
344  *
345  * @param dma A DMA Controller handle.
346  * @param clear_state Enable interrupt clearing mechanism. The bit position
347  * corresponds to the IRQ index.
348  * @return The result of the operation.
349  */
352  uint32_t clear_state);
353 
354 /**
355  * Select the bus interface for the interrupt clearing mechanism.
356  * 0: CTN/System fabric
357  * 1: OT-internal crossbar
358  *
359  * @param dma A DMA Controller handle.
360  * @param clear_irq_bus Bus selection for the clearing mechanism. The bit
361  * position corresponds to the IRQ index.
362  * @return The result of the operation.
363  */
366  uint32_t clear_irq_bus);
367 
368 /**
369  * Address index for every interrupt. Used to configure the write address and
370  * write value for the interrupt clearing mechanism.
371  */
372 typedef enum dif_dma_intr_idx {
373  kDifDmaIntrClearIdx0 = 0x0,
374  kDifDmaIntrClearIdx1 = 0x4,
375  kDifDmaIntrClearIdx2 = 0x8,
376  kDifDmaIntrClearIdx3 = 0xC,
377  kDifDmaIntrClearIdx4 = 0x10,
378  kDifDmaIntrClearIdx5 = 0x14,
379  kDifDmaIntrClearIdx6 = 0x18,
380  kDifDmaIntrClearIdx7 = 0x1C,
381  kDifDmaIntrClearIdx8 = 0x20,
382  kDifDmaIntrClearIdx9 = 0x24,
383  kDifDmaIntrClearIdx10 = 0x28,
385 
386 /**
387  * Set the write address for the interrupt clearing mechanism.
388  *
389  * @param dma A DMA Controller handle.
390  * @param idx Index of the selected interrupt.
391  * @param intr_src_addr Address to write the interrupt clearing value to.
392  * @return The result of the operation.
393  */
396  uint32_t intr_src_addr);
397 
398 /**
399  * Set the write value for the interrupt clearing mechanism.
400  *
401  * @param dma A DMA Controller handle.
402  * @param idx Index of the selected interrupt.
403  * @param intr_src_value Value to write the interrupt clearing value to.
404  * @return The result of the operation.
405  */
408  dif_dma_intr_idx_t idx,
409  uint32_t intr_src_value);
410 
411 #ifdef __cplusplus
412 } // extern "C"
413 #endif // __cplusplus
414 
415 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_DMA_H_