1. HSM启动与初始化验证
任务说明
本案例面向RH850/U2A系列MCU的HSM(硬件安全模块)验证场景,目标是在上电后确认HSM能够完成启动与初始化流程。验证范围限定为:HSM时钟配置生效、安全启动流程正常推进、HSM固件成功加载并进入就绪状态。验证手段通过读取HSM状态寄存器与启动阶段标志完成,不涉及密码运算功能测试。
验证环境与依赖
- 硬件:RH850/U2A评估板(HSM域供电正常)
- 调试器:Lauterbach Trace32 或 Renesas E2 emulator(用于连接HSM调试接口)
- 软件:Renesas CS+ 或 IAR Embedded Workbench for RH850
- 依赖文件:HSM固件镜像(hsm_fw.bin,由Renesas安全包提供,需烧录至HSM专用Flash区域)
HSM启动状态寄存器说明
HSM启动流程分为三个阶段:时钟稳定、安全启动(引导ROM校验)、固件加载。每个阶段完成后,硬件会置位对应的状态标志位。验证程序通过读取HSM状态寄存器(HSM_STS)判断当前所处阶段,并检查各阶段是否在规定超时时间内完成。
| 状态位 | 偏移 | 含义 | 置位条件 |
|---|---|---|---|
| CLK_RDY | bit0 | HSM时钟就绪 | HSM内部PLL锁定且时钟稳定 |
| BOOT_DONE | bit1 | 安全启动完成 | 引导ROM完成HSM固件签名校验 |
| FW_LOADED | bit2 | 固件加载完成 | HSM固件从Flash加载至SRAM并跳转执行 |
| HSM_READY | bit3 | HSM就绪 | 固件完成自初始化,进入空闲等待命令状态 |
关键完整代码
以下代码实现HSM启动状态的轮询验证,包含超时保护与阶段判定逻辑。代码可直接编译运行于RH850/U2A主核(锁步核),通过系统总线访问HSM寄存器。
#include <stdint.h>
#include <stdbool.h>
/* HSM寄存器映射(基地址以实际芯片手册为准) */
#define HSM_BASE_ADDR 0xF0A00000UL
#define HSM_STS_REG (*(volatile uint32_t*)(HSM_BASE_ADDR + 0x0000))
#define HSM_CTL_REG (*(volatile uint32_t*)(HSM_BASE_ADDR + 0x0004))
/* 状态位掩码 */
#define STS_CLK_RDY (1UL << 0)
#define STS_BOOT_DONE (1UL << 1)
#define STS_FW_LOADED (1UL << 2)
#define STS_HSM_READY (1UL << 3)
/* 超时参数(基于主核时钟周期数,需按实际频率调整) */
#define TIMEOUT_CLK 1000000UL /* 时钟稳定最长等待 */
#define TIMEOUT_BOOT 5000000UL /* 安全启动最长等待 */
#define TIMEOUT_FW 5000000UL /* 固件加载最长等待 */
#define TIMEOUT_READY 1000000UL /* 固件自初始化最长等待 */
/* 启动阶段枚举 */
typedef enum {
HSM_BOOT_CLK = 0,
HSM_BOOT_SECURE,
HSM_BOOT_FWLOAD,
HSM_BOOT_READY,
HSM_BOOT_FAIL
} hsm_boot_phase_t;
/* 轮询等待指定状态位置位,返回true表示成功 */
static bool wait_hsm_status(uint32_t mask, uint32_t timeout) {
uint32_t elapsed = 0;
while (elapsed < timeout) {
if ((HSM_STS_REG & mask) == mask) {
return true;
}
elapsed++;
}
return false;
}
/* HSM启动验证主函数 */
hsm_boot_phase_t hsm_verify_boot(void) {
/* 阶段1:检查HSM时钟是否稳定 */
if (!wait_hsm_status(STS_CLK_RDY, TIMEOUT_CLK)) {
return HSM_BOOT_CLK;
}
/* 阶段2:等待安全启动完成(引导ROM校验固件签名) */
if (!wait_hsm_status(STS_BOOT_DONE, TIMEOUT_BOOT)) {
return HSM_BOOT_SECURE;
}
/* 阶段3:等待固件从Flash加载至SRAM并开始执行 */
if (!wait_hsm_status(STS_FW_LOADED, TIMEOUT_FW)) {
return HSM_BOOT_FWLOAD;
}
/* 阶段4:等待固件完成自初始化,进入就绪状态 */
if (!wait_hsm_status(STS_HSM_READY, TIMEOUT_READY)) {
return HSM_BOOT_READY;
}
return HSM_BOOT_READY;
}
/* 启动HSM(触发安全启动流程) */
void hsm_trigger_boot(void) {
/* 写1到CTL寄存器的bit0,触发HSM复位释放并开始启动 */
HSM_CTL_REG |= (1UL << 0);
}
/* 主函数入口 */
int main(void) {
hsm_boot_phase_t phase;
/* 触发HSM启动 */
hsm_trigger_boot();
/* 执行启动验证 */
phase = hsm_verify_boot();
/* 结果判定:仅当返回READY时验证通过 */
if (phase == HSM_BOOT_READY) {
/* 验证通过:HSM已完成全部启动流程 */
return 0;
} else {
/* 验证失败:返回失败阶段编号(1~4对应各阶段) */
return (int)phase + 1;
}
}
编译与运行
- 在CS+或IAR中创建RH850/U2A工程,将上述代码添加至主程序文件。
- 将HSM固件镜像(hsm_fw.bin)烧录至HSM专用Flash区域(地址由Renesas安全包说明指定)。
- 编译工程,生成可执行文件后通过调试器下载至目标板。
- 全速运行程序,观察main函数返回值。
验证方法与判定标准
- 通过条件:main函数返回0,表示HSM已完成时钟配置、安全启动、固件加载并进入就绪状态。
- 失败定位:若返回值非0,根据返回值判断失败阶段:
- 返回1:时钟稳定超时——检查HSM供电、外部晶振或PLL配置
- 返回2:安全启动超时——检查HSM固件签名是否正确、引导ROM是否被意外禁用
- 返回3:固件加载超时——检查HSM Flash区域烧录内容、加载地址配置
- 返回4:固件自初始化超时——检查HSM固件版本与主核通信配置是否匹配
- 辅助观察:在调试器中添加变量
phase的实时监视,可观察启动过程推进到哪个阶段后停滞。
常见问题
- HSM_STS寄存器始终为0:确认主核与HSM之间的总线访问权限已使能,部分型号需在复位后配置总线主控寄存器。
- 时钟稳定标志一直不置位:检查HSM独立供电引脚电压是否在规格范围内,以及外部参考时钟是否稳定输出。
- 固件加载后HSM复位:通常为固件校验失败触发安全机制,需重新生成并烧录签名正确的固件镜像。