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_BYTES | 4 | DMA 源物理地址最小对齐要求 |
HAL_HASH_DMA_BLOCK_BYTES | 64 | HASH DMA 的 512-bit block |
HAL_HASH_MAX_BLOCK_BYTES | 128 | SHA-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);| 算法 | Block | Digest | 长度字段 |
|---|---|---|---|
| MD5 | 64 B | 16 B | 8 B little-endian |
| SHA-1 | 64 B | 20 B | 8 B big-endian |
| SHA-224 | 64 B | 28 B | 8 B big-endian |
| SHA-256 | 64 B | 32 B | 8 B big-endian |
| SHA-384 | 128 B | 48 B | 16 B big-endian |
| SHA-512 | 128 B | 64 B | 16 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 | 本次会话使用的算法。 |
mode | CPU 或 DMA。 |
dma_source_phys_addr | DMA 固定源物理地址。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 |
ACTIVE | round 活跃,可提交输入或读取最终 digest |
WAITING | CPU/DMA 输入已提交,等待 ORD/MRD |
ERROR | IRQ 路径检测到异常 |
调用方必须将 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_BUSY | handle 已在使用 |
IM_ERR_HARDWARE | HASH 时钟门控打开失败 |
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 / 4words 写入
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()