dif_dma.h
To use this DIF, include the following C header:
#include "/home/runner/work/opentitan/opentitan/sw/device/lib/dif/dif_dma.h"
This header provides the following device interface functions:
dif_dma_abort
Abort the DMA Controller transaction in execution.dif_dma_configure
Configures DMA Controller for a transaction.dif_dma_error_code_get
Reads the DMA error code.dif_dma_get_digest_length
Return the digest length given a DMA opcode.dif_dma_handshake_clear_irq
Enable the corresponding DME handshake interrupt clearing mechanism.dif_dma_handshake_clear_irq_bus
Select the bus interface for the interrupt clearing mechanism.dif_dma_handshake_disable
Disable DMA Controller hardware handshake mode.dif_dma_handshake_enable
Configures DMA Controller hardware handshake mode.dif_dma_handshake_irq_enable
Enable DMA controller handshake interrupt.dif_dma_intr_src_addr
Set the write address for the interrupt clearing mechanism.dif_dma_intr_write_value
Set the write value for the interrupt clearing mechanism.dif_dma_is_memory_range_locked
Checks whether the DMA memory range is locked.dif_dma_is_memory_range_valid
Checks whether the DMA memory range is valid.dif_dma_memory_range_get
Get the DMA enabled memory range within the OT internal memory space.dif_dma_memory_range_lock
Locks out the DMA memory range register.dif_dma_memory_range_set
Set the DMA enabled memory range within the OT internal memory space.dif_dma_sha2_digest_get
Read out the SHA2 digest.dif_dma_start
Begins a DMA Controller transaction.dif_dma_status_clear
Clear all status bits of the status register.dif_dma_status_get
Reads the DMA status.dif_dma_status_poll
Poll the DMA status util a given flag in the register is set.dif_dma_status_write
Writes the DMA status register and clears the corrsponding status bits.
Generated from dif_dma.h
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_DMA_H_
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_DMA_H_
/**
* @file
* @brief <a href="/hw/ip/dma/doc/">DMA Controller</a> Device Interface
* Functions
*/
#include <stdint.h>
#include "dma_regs.h" // Generated.
#include "sw/device/lib/dif/autogen/dif_dma_autogen.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// Target Address space that the source address pointer refers to.
typedef enum dif_dma_address_space_id {
/* OpenTitan 32 bit internal bus. */
kDifDmaOpentitanInternalBus = 0x07,
/* SoC control register address bus using 32 bit (or 64 bits if configured by
an SoC) CTN port .*/
kDifDmaSoCControlRegisterBus = 0x0a,
/* SoC system address bus using 64 bit SYS port. */
kDifDmaSoCSystemBus = 0x09,
} dif_dma_address_space_id_t;
/* Supported transaction widths by the DMA */
typedef enum dif_dma_transaction_width {
/* Transfer 1 byte at a time.*/
kDifDmaTransWidth1Byte = 0x00,
/* Transfer 2 byte at a time.*/
kDifDmaTransWidth2Bytes = 0x01,
/* Transfer 4 byte at a time.*/
kDifDmaTransWidth4Bytes = 0x02,
} dif_dma_transaction_width_t;
/* Supported Opcodes by the DMA */
typedef enum dif_dma_transaction_opcode {
/* Simple copy from source to destination.*/
kDifDmaCopyOpcode = 0x00,
/* Inline hashing with SHA2-256.*/
kDifDmaSha256Opcode = 0x01,
/* Inline hashing with SHA2-384.*/
kDifDmaSha384Opcode = 0x02,
/* Inline hashing with SHA2-512.*/
kDifDmaSha512Opcode = 0x03,
} dif_dma_transaction_opcode_t;
/**
* Define the transaction address space.
*/
typedef struct dif_dma_transaction_address {
uint64_t address;
dif_dma_address_space_id_t asid;
} dif_dma_transaction_address_t;
/**
* Addressing configuration.
*/
typedef struct dif_dma_address_config {
/* Address wraps after each chunk, so chunks overlap */
bool wrap;
/* Increment after each (partial-)word transfer */
bool increment;
} dif_dma_address_config_t;
/**
* Parameters for a DMA Controller transaction.
*/
typedef struct dif_dma_transaction {
dif_dma_transaction_address_t source;
dif_dma_transaction_address_t destination;
dif_dma_address_config_t src_config;
dif_dma_address_config_t dst_config;
/* Chunk size (in bytes) of the data object to transferred.*/
size_t chunk_size;
/* Total size (in bytes) of the data object to transferred.*/
size_t total_size;
/* Iteration width.*/
dif_dma_transaction_width_t width;
} dif_dma_transaction_t;
/**
* Configures DMA Controller for a transaction.
*
* This function should be called every time before `dif_dma_start`.
*
* @param dma A DMA Controller handle.
* @param config Transaction configuration parameters.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_configure(const dif_dma_t *dma,
dif_dma_transaction_t transaction);
/**
* Configures DMA Controller hardware handshake mode.
*
* This function should be called before `dif_dma_start`.
*
* Hardware handshake mode is used to push / pop FIFOs to / from low speed IO
* peripherals receiving data e.g. I3C receive buffer.
*
* @param dma A DMA Controller handle.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_handshake_enable(const dif_dma_t *dma);
/**
* Disable DMA Controller hardware handshake mode.
*
* @param dma A DMA Controller handle.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_handshake_disable(const dif_dma_t *dma);
/**
* Begins a DMA Controller transaction.
*
* Before this function the DMA transaction shall be configured by calling the
* function `dif_dma_configure` and optionally `dif_dma_handshake_enable` can be
* called.
*
* @param dma A DMA Controller handle.
* @param opcode Transaction opcode.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_start(const dif_dma_t *dma,
dif_dma_transaction_opcode_t opcode);
/**
* Abort the DMA Controller transaction in execution.
*
* @param dma A DMA Controller handle.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_abort(const dif_dma_t *dma);
/**
* Set the DMA enabled memory range within the OT internal memory space.
*
* @param dma A DMA Controller handle.
* @param address Base address.
* @param size The range size.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_memory_range_set(const dif_dma_t *dma, uint32_t address,
size_t size);
/**
* Get the DMA enabled memory range within the OT internal memory space.
*
* @param dma A DMA Controller handle.
* @param[out] address Out-param for the base address.
* @param[out] size Out-param for the range size.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_memory_range_get(const dif_dma_t *dma, uint32_t *address,
size_t *size);
/**
* Locks out the DMA memory range register.
*
* This function is reentrant: calling it while functionality is locked will
* have no effect and return `kDifOk`.
*
* @param dma A DMA Controller handle.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_memory_range_lock(const dif_dma_t *dma);
/**
* Checks whether the DMA memory range is locked.
*
* @param dma A DMA Controller handle.
* @param[out] is_locked Out-param for the locked state.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_is_memory_range_locked(const dif_dma_t *dma,
bool *is_locked);
/**
* Checks whether the DMA memory range is valid.
*
* @param dma A DMA Controller handle.
* @param[out] is_valid Out-param for the valid state.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_is_memory_range_valid(const dif_dma_t *dma,
bool *is_valid);
typedef enum dif_dma_status_code {
// DMA operation is active.
kDifDmaStatusBusy = 0x01 << DMA_STATUS_BUSY_BIT,
// Configured DMA operation is complete.
kDifDmaStatusDone = 0x01 << DMA_STATUS_DONE_BIT,
// Set once aborted operation drains.
kDifDmaStatusAborted = 0x01 << DMA_STATUS_ABORTED_BIT,
// Error occurred during the operation.
// Check the error_code for information about the source of the error.
kDifDmaStatusError = 0x01 << DMA_STATUS_ERROR_BIT,
// Set once the SHA2 digest is valid after finishing a transfer
kDifDmaStatusSha2DigestValid = 0x01 << DMA_STATUS_SHA2_DIGEST_VALID_BIT,
// Transfer of a single chunk is complete.
kDifDmaStatusChunkDone = 0x01 << DMA_STATUS_CHUNK_DONE_BIT,
} dif_dma_status_code_t;
/**
* Bitmask with the `dif_dma_status_code_t` values.
*/
typedef uint32_t dif_dma_status_t;
/**
* Reads the DMA status.
*
* @param dma A DMA Controller handle.
* @param[out] status Out-param for the status.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_status_get(const dif_dma_t *dma, dif_dma_status_t *status);
/**
* Writes the DMA status register and clears the corrsponding status bits.
*
* @param dma A DMA Controller handle.
* @param status Status bits to be cleared.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_status_write(const dif_dma_t *dma,
dif_dma_status_t status);
/**
* Clear all status bits of the status register.
*
* @param dma A DMA Controller handle.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_status_clear(const dif_dma_t *dma);
/**
* Poll the DMA status util a given flag in the register is set.
*
* @param dma A DMA Controller handle.
* @param flag The status that needs to bet set.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_status_poll(const dif_dma_t *dma,
dif_dma_status_code_t flag);
typedef enum dif_dma_error_code {
// Source address error.
kDifDmaErrorNone = 0x00,
// Source address error.
kDifDmaErrorSourceAddress = 0x01 << 0,
// Destination address error.
kDifDmaErrorDestinationAddress = 0x01 << 1,
// Opcode error.
kDifDmaErrorOpcode = 0x01 << 2,
// Size error.
kDifDmaErrorSize = 0x01 << 3,
// Bus transaction error.
kDifDmaErrorBus = 0x01 << 4,
// DMA enable memory config error.
kDifDmaErrorEnableMemoryConfig = 0x01 << 5,
// Register range valid error.
kDifDmaErrorRangeValid = 0x01 << 6,
// Invalid ASID error.
kDifDmaErrorInvalidAsid = 0x01 << 7,
} dif_dma_error_code_t;
/**
* Reads the DMA error code.
*
* @param dma A DMA Controller handle.
* @param[out] error Out-param for the error code.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_error_code_get(const dif_dma_t *dma,
dif_dma_error_code_t *error);
/**
* Return the digest length given a DMA opcode.
*
* @param opcode A DMA opcode.
* @param digest_len The digest length.
* @return The result of the operation.
*/
dif_result_t dif_dma_get_digest_length(dif_dma_transaction_opcode_t opcode,
uint32_t *digest_len);
/**
* Read out the SHA2 digest
*
* @param dma A DMA Controller handle.
* @param opcode The opcode to select the length of the read digest.
* @param[out] digest Pointer to the digest, to store the read values.
* @return The result of the operation.
*/
dif_result_t dif_dma_sha2_digest_get(const dif_dma_t *dma,
dif_dma_transaction_opcode_t opcode,
uint32_t digest[]);
/**
* Enable DMA controller handshake interrupt.
*
* @param dma A DMA Controller handle.
* @param enable_state Enable state. The bit position corresponds to the IRQ
* index.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_handshake_irq_enable(const dif_dma_t *dma,
uint32_t enable_state);
/**
* Enable the corresponding DME handshake interrupt clearing mechanism.
*
* @param dma A DMA Controller handle.
* @param clear_state Enable interrupt clearing mechanism. The bit position
* corresponds to the IRQ index.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_handshake_clear_irq(const dif_dma_t *dma,
uint32_t clear_state);
/**
* Select the bus interface for the interrupt clearing mechanism.
* 0: CTN/System fabric
* 1: OT-internal crossbar
*
* @param dma A DMA Controller handle.
* @param clear_irq_bus Bus selection for the clearing mechanism. The bit
* position corresponds to the IRQ index.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_handshake_clear_irq_bus(const dif_dma_t *dma,
uint32_t clear_irq_bus);
/**
* Address index for every interrupt. Used to configure the write address and
* write value for the interrupt clearing mechanism.
*/
typedef enum dif_dma_intr_idx {
kDifDmaIntrClearIdx0 = 0x0,
kDifDmaIntrClearIdx1 = 0x4,
kDifDmaIntrClearIdx2 = 0x8,
kDifDmaIntrClearIdx3 = 0xC,
kDifDmaIntrClearIdx4 = 0x10,
kDifDmaIntrClearIdx5 = 0x14,
kDifDmaIntrClearIdx6 = 0x18,
kDifDmaIntrClearIdx7 = 0x1C,
kDifDmaIntrClearIdx8 = 0x20,
kDifDmaIntrClearIdx9 = 0x24,
kDifDmaIntrClearIdx10 = 0x28,
} dif_dma_intr_idx_t;
/**
* Set the write address for the interrupt clearing mechanism.
*
* @param dma A DMA Controller handle.
* @param idx Index of the selected interrupt.
* @param intr_src_addr Address to write the interrupt clearing value to.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_intr_src_addr(const dif_dma_t *dma, dif_dma_intr_idx_t idx,
uint32_t intr_src_addr);
/**
* Set the write value for the interrupt clearing mechanism.
*
* @param dma A DMA Controller handle.
* @param idx Index of the selected interrupt.
* @param intr_src_value Value to write the interrupt clearing value to.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_dma_intr_write_value(const dif_dma_t *dma,
dif_dma_intr_idx_t idx,
uint32_t intr_src_value);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_DMA_H_