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  // Transfer of a single chunk is complete.
230  kDifDmaStatusChunkDone = 0x01 << DMA_STATUS_CHUNK_DONE_BIT,
231 } dif_dma_status_code_t;
232 
233 /**
234  * Bitmask with the `dif_dma_status_code_t` values.
235  */
236 typedef uint32_t dif_dma_status_t;
237 /**
238  * Reads the DMA status.
239  *
240  * @param dma A DMA Controller handle.
241  * @param[out] status Out-param for the status.
242  * @return The result of the operation.
243  */
246 
247 /**
248  * Writes the DMA status register and clears the corrsponding status bits.
249  *
250  * @param dma A DMA Controller handle.
251  * @param status Status bits to be cleared.
252  * @return The result of the operation.
253  */
257 
258 /**
259  * Clear all status bits of the status register.
260  *
261  * @param dma A DMA Controller handle.
262  * @return The result of the operation.
263  */
266 
267 /**
268  * Poll the DMA status util a given flag in the register is set.
269  *
270  * @param dma A DMA Controller handle.
271  * @param flag The status that needs to bet set.
272  * @return The result of the operation.
273  */
276  dif_dma_status_code_t flag);
277 
278 typedef enum dif_dma_error_code {
279  // Source address error.
280  kDifDmaErrorNone = 0x00,
281  // Source address error.
282  kDifDmaErrorSourceAddress = 0x01 << 0,
283  // Destination address error.
284  kDifDmaErrorDestinationAddress = 0x01 << 1,
285  // Opcode error.
286  kDifDmaErrorOpcode = 0x01 << 2,
287  // Size error.
288  kDifDmaErrorSize = 0x01 << 3,
289  // Bus transaction error.
290  kDifDmaErrorBus = 0x01 << 4,
291  // DMA enable memory config error.
292  kDifDmaErrorEnableMemoryConfig = 0x01 << 5,
293  // Register range valid error.
294  kDifDmaErrorRangeValid = 0x01 << 6,
295  // Invalid ASID error.
296  kDifDmaErrorInvalidAsid = 0x01 << 7,
297 } dif_dma_error_code_t;
298 
299 /**
300  * Reads the DMA error code.
301  *
302  * @param dma A DMA Controller handle.
303  * @param[out] error Out-param for the error code.
304  * @return The result of the operation.
305  */
308  dif_dma_error_code_t *error);
309 
310 /**
311  * Return the digest length given a DMA opcode.
312  *
313  * @param opcode A DMA opcode.
314  * @param digest_len The digest length.
315  * @return The result of the operation.
316  */
317 dif_result_t dif_dma_get_digest_length(dif_dma_transaction_opcode_t opcode,
318  uint32_t *digest_len);
319 
320 /**
321  * Read out the SHA2 digest
322  *
323  * @param dma A DMA Controller handle.
324  * @param opcode The opcode to select the length of the read digest.
325  * @param[out] digest Pointer to the digest, to store the read values.
326  * @return The result of the operation.
327  */
329  dif_dma_transaction_opcode_t opcode,
330  uint32_t digest[]);
331 
332 /**
333  * Enable DMA controller handshake interrupt.
334  *
335  * @param dma A DMA Controller handle.
336  * @param enable_state Enable state. The bit position corresponds to the IRQ
337  * index.
338  * @return The result of the operation.
339  */
342  uint32_t enable_state);
343 
344 /**
345  * Enable the corresponding DME handshake interrupt clearing mechanism.
346  *
347  * @param dma A DMA Controller handle.
348  * @param clear_state Enable interrupt clearing mechanism. The bit position
349  * corresponds to the IRQ index.
350  * @return The result of the operation.
351  */
354  uint32_t clear_state);
355 
356 /**
357  * Select the bus interface for the interrupt clearing mechanism.
358  * 0: CTN/System fabric
359  * 1: OT-internal crossbar
360  *
361  * @param dma A DMA Controller handle.
362  * @param clear_irq_bus Bus selection for the clearing mechanism. The bit
363  * position corresponds to the IRQ index.
364  * @return The result of the operation.
365  */
368  uint32_t clear_irq_bus);
369 
370 /**
371  * Address index for every interrupt. Used to configure the write address and
372  * write value for the interrupt clearing mechanism.
373  */
374 typedef enum dif_dma_intr_idx {
375  kDifDmaIntrClearIdx0 = 0x0,
376  kDifDmaIntrClearIdx1 = 0x4,
377  kDifDmaIntrClearIdx2 = 0x8,
378  kDifDmaIntrClearIdx3 = 0xC,
379  kDifDmaIntrClearIdx4 = 0x10,
380  kDifDmaIntrClearIdx5 = 0x14,
381  kDifDmaIntrClearIdx6 = 0x18,
382  kDifDmaIntrClearIdx7 = 0x1C,
383  kDifDmaIntrClearIdx8 = 0x20,
384  kDifDmaIntrClearIdx9 = 0x24,
385  kDifDmaIntrClearIdx10 = 0x28,
387 
388 /**
389  * Set the write address for the interrupt clearing mechanism.
390  *
391  * @param dma A DMA Controller handle.
392  * @param idx Index of the selected interrupt.
393  * @param intr_src_addr Address to write the interrupt clearing value to.
394  * @return The result of the operation.
395  */
398  uint32_t intr_src_addr);
399 
400 /**
401  * Set the write value for the interrupt clearing mechanism.
402  *
403  * @param dma A DMA Controller handle.
404  * @param idx Index of the selected interrupt.
405  * @param intr_src_value Value to write the interrupt clearing value to.
406  * @return The result of the operation.
407  */
410  dif_dma_intr_idx_t idx,
411  uint32_t intr_src_value);
412 
413 #ifdef __cplusplus
414 } // extern "C"
415 #endif // __cplusplus
416 
417 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_DMA_H_