API GUIDE / AES / OVERVIEW

G32S10 AES API 概述

模块概述:本文档定义 G32S10 SDK 当前通用 AES 引擎的正式接口,覆盖以下两层:

1. 文档范围

本文档定义 G32S10 SDK 当前通用 AES 引擎的正式接口,覆盖以下两层:

  • HAL AES:面向应用、BSP、示例和驱动上层的分阶段功能接口

  • LL AES:面向寄存器与位操作的低层接口

本文档基于以下实现与头文件编写:

  • code/include/drivers/g32s10/aes/hal_aes.h

  • code/include/drivers/g32s10/aes/ll_aes.h

  • code/include/drivers/g32s10/aes/aes_regs.h

  • code/drivers/g32s10/aes/hal_aes.c

补充说明:

  • HAL 负责配置结构默认值、AES 时钟门控、会话状态、CPU/DMA/EFUSE 操作启动、局部中断控制、IRQ 状态确认、callback 分发、结果读取、abort、deinit 和调试 dump。

  • HAL 不负责 SoC IRQ 的申请、使能、关闭与释放,也不提供线程等待队列。

  • HAL 不负责 DMA staging buffer、cache clean/invalidate、虚拟地址到物理地址转换、整包分段、CBC IV 链式更新或应用层 callback。

  • LL 层只封装寄存器访问,不维护软件状态,不做参数校验、超时等待、cache 操作或 callback。

  • 本文件描述通用 AES 模块。

2. 分层关系

APPLICATION  Application / middleware / test  业务代码、板级支持与示例入口
↓
HAL  HAL AES  模块级配置、状态管理与硬件访问
↓
LL  LL AES  寄存器访问与字段级控制
↓
HARDWARE REGISTERS  AES registers  实例地址、寄存器布局与位域定义

分层职责如下:

  • HAL AES

    • 管理一个 caller-owned hal_aes_handle_t

    • 管理 HAL_CPM_ID_GATE_AES 时钟门控

    • 配置软件 key、EFUSE key、ECB/CBC、方向、key length、IV 和 endian

    • 提供 CPU block、DMA segment、EFUSE key/id read 三类启动原语

    • 通过 hal_aes_irq_handler() 将局部完成位转换成 HAL callback

    • 提供 abort、deinit 和可选寄存器 dump

  • LL AES

    • 提供 static inline 寄存器 helper

    • 不管理时钟、状态、超时、cache、IRQ 或数据顺序

    • read-modify-write helper 不具备并发保护

  • aes_regs.h

    • 定义 AES 实例、寄存器布局、位域和基本 block/key/IV 尺寸

3. 资源模型与公开类型

3.1 EFUSE 请求

typedef struct {
    hal_aes_efuse_key_mode_t efuse_key_mode;
    bool id_fusion_enable;
    bool use_efuse_key;
} hal_aes_efuse_request_t;

字段说明:

字段类型零初始化默认值约束与说明
efuse_key_modehal_aes_efuse_key_mode_tmode 0必须为 mode 0 到 mode 3;该值写入 ASCR.EKEY_MODE。
id_fusion_enableboolfalse为 true 时设置 ASCR.ID_FUSION,否则清除该位。
use_efuse_keyboolfalse保留给上层描述 key-source 策略。当前 hal_aes_efuse_key_read_start() 和 hal_aes_efuse_id_read_start() 不读取该字段,也不直接改写 ASCR.EKEY_USE。

构造约束:

  • 推荐先使用 hal_aes_efuse_request_t request = {0}; 零初始化,再显式设置需要的字段。

  • efuse_key_mode 会由启动接口检查;非法值返回 IM_ERR_INVALID_PARAM。

  • id_fusion_enable 按布尔值写入 ASCR.ID_FUSION。

  • use_efuse_key 不属于当前 EFUSE read 启动逻辑。后续 CPU/DMA block 使用 EFUSE key 时,应设置运算 descriptor 中的 key_source = HAL_AES_KEY_SOURCE_EFUSE。

  • request 内容在启动接口返回前已经消费,调用方无需在等待 EKEY_RDD/EID_RDD 期间继续保持该对象有效。

3.2 HAL handle 与状态

typedef struct hal_aes_handle hal_aes_handle_t;

当前头文件公开了结构体字段用于 caller-owned static storage,但调用方必须将其视为 HAL 私有状态:

  • 首次调用 hal_aes_init() 前必须全 0 初始化。

  • 不得直接修改 state、callback、clock 或 key 相关字段。

  • 重新初始化前必须先调用 hal_aes_deinit()。

  • 一个 handle 同时只能承载一个硬件操作。

状态类型为 hal_aes_state_t,状态机如下:

状态含义
HAL_AES_STATE_RESET未初始化或已 deinit。
HAL_AES_STATE_READY已初始化且可开始 CPU、DMA 或 EFUSE 原语。
HAL_AES_STATE_WAITING_CPUCPU block 已启动,等待 ASSR.AESD。
HAL_AES_STATE_WAITING_DMADMA segment 已启动,等待 ASSR.DMAD。
HAL_AES_STATE_WAITING_EKEYRDEFUSE key read 已启动,等待 ASSR.EKEY_RDD。
HAL_AES_STATE_WAITING_EIDRDEFUSE chip-id read 已启动,等待 ASSR.EID_RDD。
HAL_AES_STATE_ERROR错误保留状态,调用方应通过 hal_aes_abort() 恢复。

除 hal_aes_abort() 和 hal_aes_deinit() 外,启动类接口通常要求当前状态为 READY,否则返回 IM_ERR_BUSY。

3.3 callback

typedef enum {
    HAL_AES_CALLBACK_CPU_DONE = 0,
    HAL_AES_CALLBACK_DMA_DONE,
    HAL_AES_CALLBACK_EKEYRD_DONE,
    HAL_AES_CALLBACK_EIDRD_DONE,
    HAL_AES_CALLBACK_COUNT,
} hal_aes_callback_type_t;

typedef void (*hal_aes_callback_t)(hal_aes_handle_t *haes,
                                   error_code_t status,
                                   void *user_data);

说明:

  • 每个 callback slot 只保存一个函数指针。

  • 所有 slot 共用一个 user_data,由 hal_aes_user_data_set() 设置。

  • 当前 HAL 只在对应完成位置位且状态匹配时以 status = IM_OK 调用 callback。

  • callback 从 hal_aes_irq_handler() 调用,属于 IRQ 上下文;不得阻塞、休眠、等待互斥锁或执行耗时日志。

4. CPU、DMA 与 EFUSE 操作流程

4.1 EFUSE reset-read

hal_aes_efuse_reset_read_wait()
  -> poll ASSR.EKEY_RSTD
  -> IM_OK

该路径没有中断;必须在任务上下文调用。

5. 典型用法

5.1 DMA segment

hal_aes_dma_segment_t segment = {
    .direction = HAL_AES_DIRECTION_ENCRYPT,
    .mode = HAL_AES_MODE_CBC,
    .key_length = HAL_AES_KEY_LENGTH_128,
    .key_source = HAL_AES_KEY_SOURCE_SOFTWARE,
    .key = key,
    .key_size_bytes = 16U,
    .iv = iv,
    .src_phys_addr = src_phys,
    .dst_phys_addr = dst_phys,
    .byte_count = bytes,
};

im_cache_data_clean_by_addr(src, bytes);
im_cache_data_clean_invalidate_by_addr(dst, bytes);
ret = hal_aes_dma_segment_start(&aes, &segment);
/* DMAD 回调后 invalidate dst,再读取结果。 */

完整可运行示例:

  • code/examples/hal/aes_hal_example.c

  • code/examples/ll/aes_ll_example.c

5.2 LL DMA

LL 使用步骤:

  1. 调用 hal_cpm_clk_enable(HAL_CPM_ID_GATE_AES)。

  2. 配置 ASCR、key、IV、DMA 地址、word count 和 block count。

  3. 执行 cache clean/invalidate 和虚拟地址转换。

  4. 置位 ASCR.DMAS。

  5. 轮询 ASSR.DMAD 或使用 ASINTEN/IRQ。

  6. invalidate 输出 cache。

  7. 清除 DMAD,关闭 DMA 和 AES。

  8. 调用 hal_cpm_clk_disable(HAL_CPM_ID_GATE_AES)。

6. 推荐关注的错误码

错误码典型来源
IM_OK操作成功。
IM_ERR_INVALID_PARAM空指针、非法实例、非法枚举、非法 key 组合、未对齐 DMA 长度。
IM_ERR_NOT_READYhandle 未初始化、状态不满足读取要求、EFUSE reset-read 状态已失效、systick 未初始化。
IM_ERR_BUSYhandle 已初始化、状态机不处于 READY。
IM_ERR_HARDWAREAES 时钟门控打开失败。
IM_ERR_TIMEOUTEFUSE reset-read 轮询超时。
IM_ERR_UNSUPPORTEDdebug helper 未编译。