*openUBMC 支持CPLD固件安全自检详细设计说明书*

<table>
    <tr>
        <td>所属SIG组:</td>
        <td>hardware</td>
    </tr>
    <tr>
        <td>落入版本:</td>
        <td>26.03</td>
    </tr>
    <tr>
        <td>设计人员:</td>
        <td>lidonghui</td>
    </tr>
    <tr>
        <td>日期:</td>
        <td>2026/01/21</td>
    </tr>
</table>

**Copyright © 2026 openUBMC Community**

您对&quot;本文档&quot;的复制，使用，修改及分发受木兰宽松许可证, 第2版协议(以下简称&quot;MulanPSL2&quot;)的约束。  
为了方便用户理解，您可以通过访问<https://license.coscl.org.cn/MulanPSL2>了解MulanPSL2的概要 (但不是替代)。  
MulanPSL2的完整协议内容您可以访问如下网址获取：<https://license.coscl.org.cn/MulanPSL2>。

**改版记录**

<table>
    <tr>
        <th>日期</th>
        <th>修订版本</th>
        <th>修订描述</th>
        <th>作者</th>
        <th>审核</th>
    </tr>
    <tr>
        <td>2026/01/21</td>
        <td>1.0</td>
        <td>新增CPLD固件安全自检功能</td>
        <td>xxx</td>
        <td>xxx</td>
    </tr>
</table>

**List of abbreviations  缩略语清单：**

<table>
    <tr>
        <th>Abbreviations 缩略语</th>
        <th>Full spelling 英文全名</th>
        <th>Chinese explanation 中文解释</th>
    </tr>
    <tr>
        <td>CPLD</td>
        <td>Complex Programmable Logic Device</td>
        <td>复杂可编程逻辑器件</td>
    </tr>
    <tr>
        <td>SVF</td>
        <td>Serial Vector Format</td>
        <td>串行矢量格式，是一种行业标准文件格式</td>
    </tr>
    <tr>
        <td>JTAG</td>
        <td>Joint Test Action Group</td>
        <td>联合测试行动小组标准接口，用于在线编程和功能测试</td>
    </tr>
</table>


## 1. 功能分析

### 1.1 功能背景

在进行安全测试时，攻破BMC后，通过升级经过篡改的CPLD可以锁死当前节点的NPU卡，进一步切断BMC通道后，形成NPU算力可用性勒索攻击。</br>
因此需要提供一种方式对CPLD升级固件进行安全校验，该详设主要介绍general_hardware如何发送安全校验文件给CPLD并记录校验结果相关内容。</br>

### 1.2 功能描述

general_hardware主要提供校验文件的发送与校验结果记录的功能：</br>
1.监听固件管理提供的自检信号</br>
2.识别hpm包中的verify文件</br>
3.复用升级流程把verify文件传递到CPLD</br>
 

### 1.3 功能场景
1.在CSR中配置自检下发时间， BMC启动后等待对应的时间下发CPLD自检流程

### 1.4 功能列表

| 功能编号 | 功能标题 | 功能描述 |
| ------- | ------- | -------- |
| 1 | 监听固件管理自检信号 | 启动时监听，用于触发自检流程的信号 |
| 2 | 通过升级方式把自检信号中的svf文件传递给CPLD | 复用general_hardware的CPLD升级流程把校验svf文件发送给CPLD |
| 3 | 自检结果记录 | 记录自检安全日志，并向固件管理返回自检结果 |

## 2. 功能设计

### 2.1 总体方案分析

#### 2.1.1 方案概述

1.general_hardware组件service.json新增自检信号依赖，并自动代码生成</br>
2.增加自检信号监听，提供自检回调函数</br>
3.复用原有CPLD升级流程函数process:upgrade_component_cpld将自检svf文件传递到CPLD</br>

备注：</br>
1.仅支持JTAG链路</br>
2.仅支持对NPU管理板上15k CPLD进行自检, 15K表示CPLD容量</br>

#### 2.1.2 开发视图

```mermaid
classDiagram
    class firmware_mgmt {
        + SendCpldSelfCheckSignal()
    }

    class general_hardware_service {
        + on_cpld_self_check_signal()
        + dispatch_to_cpld_self_check()
    }

    class cpld_self_check {
        + start_self_check()
        + prepare_svf_file()
        + record_result()
    }

    class cpld_upgrade {
        + upgrade_component_cpld()
    }

    class log_db {
        + CpldSelfCheckLog表
    }

    firmware_mgmt --> general_hardware_service : send self_check signal
    general_hardware_service --> cpld_self_check : callback dispatch
    cpld_self_check --> cpld_upgrade : reuse upgrade_component_cpld(SVF)
    cpld_self_check --> log_db : write self_check result
```

#### 2.1.3 运行视图

```mermaid
sequenceDiagram
    participant SYS as System/OPS
    participant FM as firmware_mgmt
    participant GHS as general_hardware_service
    participant CSC as cpld_self_check
    participant CUP as cpld_upgrade
    participant LOG as log_db

    SYS->>FM: 触发CPLD安全自检(上电/升级完成/人工)
    FM->>GHS: SendCpldSelfCheckSignal(target=NPU_CPLD)
    GHS->>CSC: on_cpld_self_check_signal(cpld_id, svf_info)
    CSC->>CSC: prepare_svf_file()
    CSC->>CUP: upgrade_component_cpld(JTAG, svf_file)
    CUP-->>CSC: 返回升级(自检执行)结果
    CSC->>LOG: record_result(成功/失败及原因)
    CSC-->>GHS: 返回自检结果
    GHS-->>FM: 回调/上报自检结果
    FM-->>SYS: 将结果暴露至北向接口/日志/告警
```

#### 2.1.4 内部依赖分析
1.依赖固件管理触发自检流程</br>
2.固件管理自检接口：https://discuss.openubmc.cn/t/topic/3596

#### 2.1.5 外部依赖分析
1.CPLD支持解析SVF校验文件并进行自检的能力</br>
2.CPLD固件包需要新增用于verify功能的svf文件</br>

#### 2.1.6 北向接口分析

| 特性 | SNMP | CLI | WEB | KVM_VMM | IPMI(RMCP/RMCP+) | HMM | Redfish |
| ---- | ---- | ---- | --- | ------ | ---------------- | --- | ------- |
| 支持CPLD固件安全自检 | 不涉及 | 不涉及 | 不涉及 | 不涉及 | 不涉及 | 不涉及 | 不涉及 | 

#### 2.1.7 兼容性分析
1.新增独立的自检流程，对已有功能无影响，不涉及兼容性</br>

#### 2.1.8 其它通用分析（定制化、导入导出、传感器、事件、系统锁定）
1.新增流程不涉及<br>

#### 2.1.9 用例场景分析

| 用例编号 | 用例描述 | 前置条件 | 执行步骤 | 预期结果 |
| --- | --- | --- | --- | --- |
| 1 | 上电阶段NPU管理板CPLD安全自检成功 | BMC正常上电；NPU管理板板上CPLD在位且支持SVF自检 | 1. 上电完成后固件管理按配置时间触发CPLD自检信号；2. general_hardware接收信号并调用自检流程；3. 查询自检结果日志 | JTAG链路正常，SVF文件下发成功，自检结果为“通过”，日志记录一次成功自检 |
| 2 | 上电阶段NPU管理板CPLD安全自检失败（篡改场景） | BMC正常上电；NPU管理板上CPLD已被刷入篡改固件，仍支持SVF执行 | 1. 上电完成后触发CPLD自检信号；2. general_hardware通过升级流程下发自检SVF；3. CPLD执行自检并返回失败；4. 查询自检结果日志 | 自检结果为“失败”，返回错误码/失败原因（如校验不通过）；general_hardware记录安全日志，供后续排查或处置 |
| 3 | 非NPU管理板CPLD场景不检测 | 没有NPU节点的机型 | 1. BMC启动等待配置时间超时；2. 查询自检结果日志 | 无自检结果，不会进入自检流程 |
| 4 | NPU管理板CPLD非15K容量 | 非15K容量的CPLD环境 | 1. 触发全局CPLD自检信号；2. general_hardware下发SVF；3. 查询自检结果 | 返回失败，不记录自检结果 |


### 2.2 非功能质量属性设计

#### 2.2.1 扩展性分析
独立功能，不涉及

#### 2.2.2 重用性分析
独立功能，不涉及

#### 2.2.3 可测试性分析
SR配置自检等待时间后，BMC复位启动后等待对应时间即可触发，通过日志观测结果</br>
1.流程日志：LogDump/app.log</br>
2.安全日志：LogDump/security.log</br>

#### 2.2.4 资源使用分析
- 自检流程一般只在BMC启动时候触发，频度较低，对CPU/内存影响较小。


#### 2.2.5 可靠性与安全性分析

| 编号 | 场景 | 问题描述 | 影响 | 建议方案/处理策略 |
| --- | --- | --- | --- | --- |
| 1 | 其他非NPU管理板CPLD触发自检 | CPLD侧如果不支持时要能正常返回 | 可能导致CPLD工作异常 | 如果CPLD无防护处理，那么BMC要进行限制，防止误触发 |
| 2 | 读取CPLD元数据失败 | 通信异常/器件异常 | 无法校验当前固件 | 日志记录报错，不记录自检结果 |
| 3 | 自检本身异常退出 | 程序异常/资源不足 | 任务中断 | 仅通过日志记录异常，不记录自检结果 |
| 4 | 非15K CPLD | CPLD在收到自检文件后，如果不支持要能正常反馈错误 | 如果CPLD不支持情况下，收到自检文件且没有防护，可能导致CPLD异常 | CPLD支持防护 |
| 5 | 自检流程任何退出的分支都要对固件管理进行Reply | 异常退出没有Reply导致固件管理流程卡死 | 固件管理自检卡死 | 异常分支保证Reply回复 |
| 5 | 自检信号和升级信号冲突 | 如果信号同时发送到general_hardware | 处于自检时则不能升级，处于升级则不能自检 | 业务处理保证只处理一个信号 |

## 3. 功能实现

### 3.1 CPLD固件安全自检实现要点

1. 流程控制： 仅NPU管理板的15K CPLD才支持自检</br>
2. 结果：不支持的仅记录日志； 支持自检，正常返回自检结果(成功/失败)才记录安全日志</br> 

### 3.2 开发者测试建议

1. **单元测试（UT）**：  
<!-- UT，主要是功能单元测试，测试对象是功能单元接口。UT测试设计要从黑盒（功能）角度设计，从输入(I)、处理（B）、预期输出（O）的角度进行用例分析设计，测试覆盖率仅作为反馈，用于分析哪些功能场景没有覆盖到，从而指导测试设计优化并补充测试用例 -->

| 组件名  | 用例类型 | 测试用例描述 | 用例名称 | 预置条件 | 操作步骤 | 预期结果 |
| ------- | -------- | ------------ | -------- | -------- | -------- | -------- |
| general_hardware | UT | 自检信号监听注册成功 | test_register_cpld_self_check_signal | 打桩firmware_mgmt信号接口 | 1.初始化general_hardware自检模块<br>2.验证调用信号订阅接口 | 自检信号监听已注册，回调函数已绑定 |
| general_hardware | UT | NPU管理板15K CPLD自检成功 | test_npu_15k_cpld_self_check_success | 打桩CPLD对象查询、upgrade_component_cpld返回成功 | 1.构造NPU管理板15K CPLD对象<br>2.调用on_cpld_self_check_signal<br>3.模拟升级流程返回成功 | 自检流程完成，安全日志记录成功结果，向固件管理Reply成功 |
| general_hardware | UT | NPU管理板15K CPLD自检失败（CPLD返回失败） | test_npu_15k_cpld_self_check_failed | 打桩CPLD对象查询、upgrade_component_cpld返回失败 | 1.构造NPU管理板15K CPLD对象<br>2.调用on_cpld_self_check_signal<br>3.模拟升级流程返回失败 | 自检流程完成，安全日志记录失败结果及原因，向固件管理Reply失败 |
| general_hardware | UT | 非NPU管理板CPLD场景不检测 | test_non_npu_cpld_skip_check | 打桩CPLD对象查询返回非NPU管理板CPLD | 1.构造非NPU管理板CPLD对象<br>2.调用on_cpld_self_check_signal | 不进入自检流程，仅记录运行日志，向固件管理Reply跳过 |
| general_hardware | UT | 非15K CPLD场景返回失败 | test_non_15k_cpld_check_failed | 打桩CPLD对象查询返回非15K容量CPLD | 1.构造NPU管理板但非15K容量CPLD对象<br>2.调用on_cpld_self_check_signal | 返回失败，不记录自检结果，仅记录运行日志，向固件管理Reply失败 |
| general_hardware | UT | CPLD不在位或JTAG链路异常 | test_cpld_not_present_or_jtag_error | 打桩CPLD对象查询返回不在位或JTAG异常 | 1.构造CPLD不在位或JTAG链路异常场景<br>2.调用on_cpld_self_check_signal | 自检失败，记录运行日志（错误原因），不记录自检结果，向固件管理Reply失败 |
| general_hardware | UT | SVF文件准备失败 | test_svf_file_prepare_failed | 打桩SVF文件准备逻辑返回失败 | 1.构造NPU管理板15K CPLD对象<br>2.调用on_cpld_self_check_signal<br>3.模拟SVF文件准备失败 | 自检失败，记录运行日志，不记录自检结果，向固件管理Reply失败 |
| general_hardware | UT | 升级流程调用失败 | test_upgrade_component_cpld_failed | 打桩upgrade_component_cpld调用异常 | 1.构造NPU管理板15K CPLD对象<br>2.调用on_cpld_self_check_signal<br>3.模拟upgrade_component_cpld抛出异常 | 异常被捕获，记录运行日志，不记录自检结果，向固件管理Reply失败 |
| general_hardware | UT | 自检流程异常退出保证Reply | test_self_check_exception_with_reply | 打桩自检流程中任意环节抛出异常 | 1.构造NPU管理板15K CPLD对象<br>2.调用on_cpld_self_check_signal<br>3.模拟流程中异常退出 | 异常被捕获，记录运行日志，无论成功失败都向固件管理Reply，不导致流程卡死 |
| general_hardware | UT | 多块NPU管理板CPLD批量自检（部分成功部分失败） | test_multiple_npu_cpld_batch_check | 打桩多个CPLD对象，部分成功部分失败 | 1.构造多个NPU管理板15K CPLD对象<br>2.调用on_cpld_self_check_signal<br>3.模拟部分CPLD自检成功、部分失败 | 每个CPLD分别产生自检结果日志（成功/失败分别记录），整体流程完成，向固件管理Reply汇总结果 |

2. **集成测试（IT）/PCST**：  
不涉及，通过UT覆盖
