API GUIDE / HASH / HAL

G32S10 HASH HAL 接口

HAL 层接口:HAL_HASH_ALG_COUNT 是数量哨兵,不是合法算法。

1. 资源与公开类型

1.1 实例与构建开关

项目值
实例宏HASH
基地址宏SC_HASH_IOBASE
基地址0x13480000
驱动开关CONFIG_DRIVER_HASH
HAL 时钟门控HAL_CPM_ID_GATE_SC_HASH
调试开关CONFIG_HASH_ENABLE_DEBUG_HELPERS
#define HASH ((hash_regs_t *)(uintptr_t)SC_HASH_IOBASE)

1.2 尺寸宏

宏值说明
HAL_HASH_DMA_BUFFER_ALIGN_BYTES4DMA 源物理地址最小对齐要求
HAL_HASH_DMA_BLOCK_BYTES64HASH DMA 的 512-bit block
HAL_HASH_MAX_BLOCK_BYTES128SHA-384/SHA-512 的最大算法 block

1.3 算法类型

typedef enum {
    HAL_HASH_ALG_MD5 = 0,
    HAL_HASH_ALG_SHA1,
    HAL_HASH_ALG_SHA224,
    HAL_HASH_ALG_SHA256,
    HAL_HASH_ALG_SHA384,
    HAL_HASH_ALG_SHA512,
    HAL_HASH_ALG_COUNT,
} hal_hash_alg_t;

HAL_HASH_ALG_COUNT 是数量哨兵,不是合法算法。

typedef enum {
    HAL_HASH_MD5_DIGEST_SIZE = 16U,
    HAL_HASH_SHA1_DIGEST_SIZE = 20U,
    HAL_HASH_SHA224_DIGEST_SIZE = 28U,
    HAL_HASH_SHA256_DIGEST_SIZE = 32U,
    HAL_HASH_SHA384_DIGEST_SIZE = 48U,
    HAL_HASH_SHA512_DIGEST_SIZE = 64U,
} hal_hash_digest_size_t;

1.4 算法元数据

typedef struct {
    uint32_t block_size_bytes;
    uint32_t digest_size_bytes;
    uint32_t length_size_bytes;
} hal_hash_alg_info_t;

bool hal_hash_alg_info_get(hal_hash_alg_t alg,
                           hal_hash_alg_info_t *info);
算法BlockDigest长度字段
MD564 B16 B8 B little-endian
SHA-164 B20 B8 B big-endian
SHA-22464 B28 B8 B big-endian
SHA-25664 B32 B8 B big-endian
SHA-384128 B48 B16 B big-endian
SHA-512128 B64 B16 B big-endian

1.5 传输模式

typedef enum {
    HAL_HASH_MODE_CPU = 0,
    HAL_HASH_MODE_DMA,
    HAL_HASH_MODE_COUNT,
} hal_hash_mode_t;
  • CPU:通过 HSDI 写完整算法 block,等待 HSSR.ORD。

  • DMA:HASH 内部 DMA 从固定物理地址读取完整算法 block,等待 HSSR.MRD。

1.6 HAL 配置

typedef struct {
    hash_regs_t *instance;
    hal_hash_alg_t alg;
    hal_hash_mode_t mode;
    uintptr_t dma_source_phys_addr;
} hal_hash_config_t;
字段说明
instance当前只接受 HASH。
alg本次会话使用的算法。
modeCPU 或 DMA。
dma_source_phys_addrDMA 固定源物理地址。CPU 模式可忽略。

DMA 地址必须非 0、不大于 UINT32_MAX,并按 HAL_HASH_DMA_BUFFER_ALIGN_BYTES 对齐。该地址在 handle 生命周期内固定。

1.7 HAL handle 与状态

typedef struct hal_hash_handle hal_hash_handle_t;
typedef enum {
    HAL_HASH_STATE_RESET = 0,
    HAL_HASH_STATE_READY,
    HAL_HASH_STATE_ACTIVE,
    HAL_HASH_STATE_WAITING,
    HAL_HASH_STATE_ERROR,
} hal_hash_state_t;
状态含义
RESET未初始化
READY已初始化,可开始 round
ACTIVEround 活跃,可提交输入或读取最终 digest
WAITINGCPU/DMA 输入已提交,等待 ORD/MRD
ERRORIRQ 路径检测到异常

调用方必须将 hal_hash_handle_t 零初始化,初始化后不得直接修改 HAL 字段。

1.8 callback

typedef enum {
    HAL_HASH_CALLBACK_CPU_DONE = 0,
    HAL_HASH_CALLBACK_DMA_DONE,
    HAL_HASH_CALLBACK_COUNT,
} hal_hash_callback_type_t;

typedef void (*hal_hash_callback_t)(hal_hash_handle_t *handle,
                                    error_code_t status,
                                    void *user_data);

callback 从 hal_hash_irq_handler() 的 IRQ 上下文调用。不得阻塞、启动下一段、生成 padding、读取 digest、维护 cache 或调用应用 callback。

2. HAL 接口

2.1 hal_hash_init

error_code_t hal_hash_init(hal_hash_handle_t *handle,
                           const hal_hash_config_t *config);

初始化 caller-owned HASH handle,校验实例、算法、模式和 DMA 地址,打开 HASH CPM gate,配置算法、字节序、DMA 模式并清除本地中断和状态。

返回:

返回值说明
IM_OK初始化成功
IM_ERR_INVALID_PARAM参数、实例、算法、模式或 DMA 地址非法
IM_ERR_BUSYhandle 已在使用
IM_ERR_HARDWAREHASH 时钟门控打开失败

2.2 callback 与 user data

error_code_t hal_hash_callback_register(
    hal_hash_handle_t *handle,
    hal_hash_callback_type_t type,
    hal_hash_callback_t callback);

error_code_t hal_hash_user_data_set(
    hal_hash_handle_t *handle,
    void *user_data);

callback = NULL 表示注销。WAITING 状态下修改 callback 或 user data 返回 IM_ERR_BUSY。

2.3 hal_hash_round_start

error_code_t hal_hash_round_start(hal_hash_handle_t *handle);

开始新 round,清除 ORD/MRD 状态,重新选择 CPU/DMA 模式,打开 controller 并置位 HSCR.INIT,状态进入 ACTIVE。

允许从 READY 或 digest 读取后的 ACTIVE 状态调用。

2.4 hal_hash_cpu_block_start

error_code_t hal_hash_cpu_block_start(
    hal_hash_handle_t *handle,
    const uint32_t *input_words,
    uint32_t word_count);

提交一个完整算法 block:

  • 必须是 CPU 模式

  • 必须先调用 hal_hash_round_start()

  • 必须已注册 CPU_DONE callback

  • word_count = block_size_bytes / 4

  • words 写入 HSDI

  • 打开 ORD interrupt,状态进入 WAITING

该接口不生成 padding。

2.5 hal_hash_dma_segment_start

error_code_t hal_hash_dma_segment_start(
    hal_hash_handle_t *handle,
    uint32_t word_count,
    uint32_t dma_block_count);

提交一个或多个完整算法 block:

  • 必须是 DMA 模式

  • 必须先调用 hal_hash_round_start()

  • 必须已注册 DMA_DONE callback

  • word_count * 4 == dma_block_count * 64

  • 总字节数必须是算法 block size 的整数倍

  • 写 HSTC/HSBNUM,打开 MRD interrupt,置位 HSCR.DMAS

HSSA 在 hal_hash_init() 中设置,segment 接口不更新地址。

2.6 hal_hash_digest_read

error_code_t hal_hash_digest_read(
    hal_hash_handle_t *handle,
    uint32_t *output_words,
    uint32_t output_word_count);

在最终 padded block 完成后读取 HSDO。必须处于 ACTIVE,且 output_word_count = digest_size_bytes / 4。成功后关闭 controller,但状态保持 ACTIVE;下一轮必须重新调用 hal_hash_round_start()。

2.7 hal_hash_irq_handler

void hal_hash_irq_handler(hal_hash_handle_t *handle);

仅处理 WAITING 状态下的 HASH IRQ。CPU 模式要求 ORD,DMA 模式要求 MRD。完成位正确时清除状态、关闭对应本地中断、进入 ACTIVE 并调用 callback;完成位不匹配时进入 ERROR,callback 收到 IM_ERR_IO。

HASH 没有独立硬件错误中断位。

2.8 hal_hash_abort

error_code_t hal_hash_abort(hal_hash_handle_t *handle);

关闭本地中断、DMA 和 controller,清除状态,重新应用控制器配置并回到 READY。不得在 IRQ 上下文调用。

2.9 hal_hash_deinit

error_code_t hal_hash_deinit(hal_hash_handle_t *handle);

停止 controller,释放 HAL_CPM_ID_GATE_SC_HASH,清零 handle。不释放 SoC IRQ;调用方必须先停止 IRQ 投递。

2.10 hal_hash_regs_dump

error_code_t hal_hash_regs_dump(const hal_hash_handle_t *handle);

仅当 CONFIG_SDK_ENABLE_DEBUG_HELPERS=y 且 CONFIG_HASH_ENABLE_DEBUG_HELPERS=y 时提供 dump,否则返回 IM_ERR_UNSUPPORTED。HSDI、HSDO、HSCG 显示为 skipped。

3. 操作流程

3.1 CPU

hal_hash_init()
hal_hash_round_start()
完整 block -> hal_hash_cpu_block_start()
WAITING -> ORD -> callback
后续完整 block 重复
最终 padded block -> callback
hal_hash_digest_read()
hal_hash_deinit()

3.2 DMA

hal_hash_init(dma_source_phys_addr)
hal_hash_round_start()
cache clean source
hal_hash_dma_segment_start()
WAITING -> MRD -> callback
后续完整 block/segment 重复
hal_hash_digest_read()
hal_hash_deinit()