*openUBMC 支持VRD固件独立升级功能详细设计说明书*

<table>
    <tr>
        <td>所属SIG组:</td>
        <td>hardware</td>
    </tr>
    <tr>
        <td>落入版本:</td>
        <td>25.09</td>
    </tr>
    <tr>
        <td>设计人员:</td>
        <td>gererdJay</td>
    </tr>
    <tr>
        <td>日期:</td>
        <td>2025/8/12</td>
    </tr>
</table>

**Copyright © 2025 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>2025/8/12</td>
        <td>1.0</td>
        <td>初稿</td>
        <td>gererdJay</td>
        <td>/</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>BMC</td>
        <td>Baseboard Management Controller</td>
        <td>基板管理控制器</td>
    </tr>
    <tr>
        <td>MCU</td>
        <td>Microcontroller Unit</td>
        <td>微控制器单元</td>
    </tr>
</table>

[TOC]

# 1.功能分析

## 1.1 功能背景
<!-- 描述该需求的来源或背景，比如：支撑XXX功能、XXX优化等；以及该需求对用户（含组件）带来什么具体价值，如果没有该需求，对用户（含组件）带来什么损失； -->
SP923H卡支持双CPLD管理，BMC需要进行适配使能

## 1.2 功能描述
<!-- 描述该需求交付的整体功能，主要实现XXX功能，解决XXX问题，明确方案如何实现 -->
本功能主要实现SP923H卡的双CPLD管理，包括：

1. **双CPLD信息显示**：CLI、web、redfish正常显示双CPLD信息
2. **双CPLD升级**：实现双CPLD独立升级

## 1.3 功能场景
<!-- 描述该需求的业务使用场景，内容包括：
1) 场景出发条件及对象：什么角色/工具/接口等在什么具体情况下使用该特性，使用对象技能如何？
2) 使用时间及频度
3) 描述该特性主要有哪些场景、子场景及关键任务操作 -->

### 1.3.1 场景触发条件及对象

- **使用角色**：系统管理员、运维人员、技术支持工程师
- **使用工具**：Web管理界面、CLI命令行、IPMI工具、Redfish API等
- **使用技能**：具备基本的BMC管理经验

### 1.3.2 使用时间及频度

- **使用时间**：系统维护窗口期、故障修复时、版本更新时
- **使用频度**：低频使用

### 1.3.3 主要场景及子场景

#### 场景1：双CPLD信息查看

- 查看双CPLD信息

#### 场景2：双CPLD独立升级

- 对CPLD进行升级

## 1.4 功能列表
<!-- 描述该需求交付的功能列表，内容包括：列出功能详细描述，标题、描述。 -->
| 功能编号 | 功能标题 | 功能描述 |
| ------- | ------- | -------- |
| F001 | 双CPLD版本信息获取 | 支持查询SP923H卡的双CPLD版本信息 |
| F002 | 双CPLD信息CLI查询 | 支持CLI查询版本信息时显示双CPLD信息 |
| F003 | 双CPLD信息web查询 | 支持web端固件版本界面显示双CPLD信息 |
| F004 | 双CPLD信息redfih查询 | 支持redfish查询固件接口显示双CPLD信息 |
| F005 | 双CPLD信息日志记录 | 记录SP923H卡的两个CPLD寄存器信息 |
| F006 | 双CPLD升级管理 | 支持SP923H的网络板和计算板的CPLD升级 |

# 2.功能设计

## 2.1 总体方案分析
<!-- 描述该方案的总体设计（注：相关输出方案可同步刷新到各组件仓） -->

### 2.1.1 方案详细设计

#### 2.1.1.1 方案概述
<!-- 描述该方案的整体实现，内容包括：涉及的关键点，实现策略等 -->
```mermaid
classDiagram
    class dpu_object {
        +cpld1_fw_id: object
        +cpld2_fw_id: object
        +fpld_fw_raw f3: object
        +fpld_fw_raw f4: object
        +fetch_cpld_fw_ver()
        +update_fw_ver()
        +get_cpld_manufacture_id()
        +regisster_cpld_firmware_info()
        +get_sdi_cpld_info()
    }
    
    class dpu_service {
        +get_fw_verion()
        +is_valid_firmware()
        +is_dpu_mcu()
        +get_vme_file()
        +on_upgrade_prepare()
        +get_fw_path()
        +upgrade_task()
    }
    class dpu_upgrade_object {
        +query_cpld_upgrade_status()
        +cpld_upgrade()
        +wait_upgrade_success()
        +wait_valid_success()
        +upgrade()
    }
    
    class utils {
        +check_CPLD_upgrade_name()
    }
    
    class std_smbus {
        +GetCpldManufacture()
        +GetCpldUpgradeStatus()
        +GetCpldFwver()
        +UpgradeFirmware()
        +ValidCpld()
    }

    dpu_service --> dpu_object
    dpu_service --> utils
    dpu_service --> dpu_upgrade_object
    dpu_object --> utils
    dpu_object --> std_smbus
    dpu_upgrade_object --> std_smbus
```

#### 2.1.1.2 开发视图
<!-- 开发视图面向系统开发及软件管理，描述系统代码结构，构建结构的视图，主要解决系统技术实现和开发的问题，它依托逻辑视图，描述代码、构建结构 -->



**代码结构说明：**

- `dpu_service`：DPU服务类，DPU服务接口
- `dpu_object`：DPU对象类，每个DPU卡创建一个DPU对象
- `dpu_upgrade_object`：DPU升级对象类，用于管理DPU升级
- `std_smbus`：smbus协议类，包含与MCU通信的opcode封装

#### 2.1.1.3 运行视图
<!-- 运行视图面向系统运行，描述系统启动过程、运行期交互的视图，主要解决系统运行期交互，描述各可执行交付件在运行期的交互关系 -->

获取CPLD版本号

```mermaid
sequenceDiagram
    participant GH as general_hardware
    participant MCU as MCU
    participant CSR as CSR

    Note over GH: 自发现初始化
    GH->>CSR: 获取DPU的BoardID
    activate CSR
    CSR->>CSR: BoardID
    CSR-->>GH: 返回
    deactivate CSR

    GH->>GH: 将BoardID替换掉cpld_fw_raw的%x占位符
    GH->>GH: 获取CPLD的厂商
    GH->>GH: 通过BoardID判断是否六口卡
    GH->>MCU: opcode：0x104a 获取两片CPLD的厂商
    GH->>GH: 将厂商ID替换掉cpld_fw_raw的_占位符
    GH->>GH: 获取CPLD的版本号
    GH->>GH: 通过BoardID判断是否六口卡
    GH->>MCU: opcode：0x1047 获取两片CPLD的版本号
    Note over GH: 更新资源树MultiLogicVersion
```

双CPLD升级prepare阶段

```mermaid
sequenceDiagram
    participant FM as firmware_mngt
    participant GH as general_hardware

    Note over FM: 开始
    FM->>FM: 读取升级包相关信息 
    FM->>GH: 升级包配置信息和升级固件路径
    GH->>GH: 确定固件升级是网络板还是计算板
    GH->>GH: 判断UID
    GH->>GH: 判断component_id
    GH->>GH: 判断厂商
    GH->>GH: 确定使用该cfg配置
    GH->>GH: 获取当前CPLD版本
    GH-->>FM: 返回
    Note over FM: 结束

```

双CPLD升级upgrade阶段

```mermaid
sequenceDiagram
    participant FM as firmware_mngt
    participant GH as general_hardware
    participant MCU as MCU

    Note over FM: 开始
    FM->>GH: 发送升级信号 
    GH->>GH: 根据升级文件名判断所升级的CPLD板
    GH->>MCU: 查询对应CPLD板的CPLD状态
    MCU->>MCU: opcode：0x1050
    MCU-->>GH:  

    Note over GH: CPLD状态是否是0、3、5、7
    alt 是
        GH->>GH: 进行升级
        GH->>MCU: 发送升级文件对应到CPLD板
        MCU->>MCU: opcode：0x1048
        MCU-->>GH:  
    else 否
        GH->>FM: 升级失败
    end

    Note over GH: 文件发送成功
    alt 是
        GH->>MCU: 查询对应CPLD板的CPLD状态
        MCU->>MCU: opcode：0x1050
        MCU-->>GH:  
    else 否
        GH->>FM: 升级失败
    end

    Note over GH: 900s内查询到状态码为3
    alt 是
        GH->>MCU: 生效对应CPLD板的CPLD升级包
        MCU->>MCU: opcode：0x1049
        MCU-->>GH:  
    else 否
        GH->>FM: 升级失败
    end

    Note over GH: 是否生效成功
    alt 是
        GH->>MCU: 查询对应CPLD板的CPLD状态
        MCU->>MCU: opcode：0x1050
        MCU-->>GH:  
    else 否
        GH->>FM: 升级失败
    end
    Note over GH: 900s内查询到状态码为0
    alt 是
        GH->>FM: 升级成功
    else 否
        GH->>FM: 升级失败
    end

    Note over FM: 结束

```

### 2.1.2 内部依赖分析
<!-- 是否涉及与其他组件接口依赖，如果涉及需要确认当前是否已完成，是否匹配当前需求开发诉求 -->
不涉及

### 2.1.3 外部依赖分析
<!-- 是否涉及与平台SDK的依赖关系 -->
需cpld为天池架构且SMC已支持支持升级

### 2.1.4 北向接口分析
<!-- 需要分析当前功能是否有以下接口影响，如果有影响，则需要具体的补充影响点。其中注意点如下：
（1）如果有新增IPMI接口，请排查代码中IPMI命令注册的过滤字段，是否完全和IPMI命令的定义一致？
（2）新增一个接口时，需要咨询SIG组是否还有其他的接口受影响 -->
| 特性 | SNMP | CLI | WEB | KVM_VMM | IPMI(RMCP/RMCP+) | HMM | Redfish |
| ---- | ---- | ---- | --- | ------ | ---------------- | --- | ------- |
| 不涉及新增 | NA | NA | NA | NA | NA | NA | NA |

### 2.1.5 兼容性分析
<!-- 当前的功能对现有在网的功能是否有影响，具体的影响点进行分析之后输出影响分析表格 -->
不影响以前Vrd升级

### 2.1.6 定制化接口分析
<!-- 如果支持定制化设置，则需要给出定制化时的默认值（空定制化项条件下的设置值），如果涉及到定制化接口变更或新增，注意定制化接口文档需配套修改。注意定制化默认值变更对白牌包的影响 -->
不涉及

### 2.1.7 导入导出分析
<!-- 如果支持导入导出的配置，则需要分析导入导出的schema。 -->
不涉及

### 2.1.8 传感器分析
<!-- 如果需要新增传感器，则需要提前登记和评审新增的传感器要素。新增传感器评审需要上SIG-Interface进行评审 -->
不涉及

### 2.1.9 精准告警事件分析
<!-- 如果需要新增事件，则需要提前登记和评审新增的时间要素 -->
不涉及

### 2.1.10 系统锁定分析
<!-- 对外的接口或者命令是否支持系统锁定 -->
不涉及

### 2.1.11 用例场景分析
<!-- 以表格的形式输出该需求涉及的用例场景 -->

| 用例编号 | 用例名称 | 用例描述 | 前置条件 | 执行步骤 | 预期结果 | 优先级 |
| ------- | ------- | ------- | ------- | ------- | ------- | ------- |
| UC001 | CPLD升级 | SP932H的网络板和计算板的CPLD升级 | 系统正常运行 | 固件升级 | CPLD升级成功 | 高 |
| UC002 | CLI查询 | 使用impcget -d v查看版本号 | 系统正常运行 | 执行ipmcget -d  v | 显示双CPLD信息 | 高 |
| UC003 | redfish查询 | redfish查询固件接口，查询CPLD信息 | 系统正常运行 | redfish查询固件接口 | 显示双CPLD信息 | 高 |
| UC004 | web界面查询 | web查看固件版本界面 | 系统正常运行 | web查看固件版本界面 | 显示双CPLD信息 | 高 |

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

### 2.2.1 扩展性分析
<!-- 考虑后续新增类似功能可以很好地扩展 -->

本设计采用模块化和可扩展的架构，具有良好的扩展性：

1. **芯片类型扩展**：通过`More_Chip`基类和工厂模式，可以轻松添加新的VRD芯片类型支持
2. **升级策略扩展**：采用策略模式，可以灵活添加新的升级策略和算法
3. **接口扩展**：基于统一的接口设计，可以zai
4. **功能扩展**：通过观察者模式，可以灵活添加新的升级事件处理逻辑

### 2.2.2 重用性分析
<!-- 是否为通用处理方式、接口，如果是得考虑重用性 -->

本设计具有良好的重用性：

1. **通用接口**：`smc_interface`提供统一的硬件通信接口，可被其他硬件管理功能重用
2. **升级框架**：升级流程框架可被其他固件升级功能重用
3. **配置管理**：VRD配置管理模块可被其他硬件配置功能重用
4. **事件机制**：观察者模式的事件机制可被其他功能重用

### 2.2.3 可测试性分析
<!-- 此需求如何验证，是否可直接验证，or通过XXX功能覆盖验证，or需要单独怎加测试接口验证 -->

可直接验证，按照测试用例覆盖测试

### 2.2.4 资料分析
<!-- 是否涉及资料修改 -->
不涉及

### 2.2.5 资源使用分析
<!-- 新增线程、内存分配、模型属性名长度是否合理，CPU占用率是否会激增，Flash中新增文件是否合理（频繁读写Flash会大幅缩短emmc寿命）；是否涉及消息队列，如果涉及请检查是否存在某些场景下消息队列会满导致消息丢失，例如大量消息发送到队列且处理消息需要耗费较长时间的场景。 -->

**资源使用分析：**

1. **线程使用**：
   - 新增1个VRD升级服务线程，占用资源较少
   - 升级过程中可能临时创建通信线程，升级完成后释放

### 2.2.6 可靠性分析

| 编号 | 场景 | 问题描述 | 可靠性影响 | 问题级别 | 建议解决方案/需求 | 讨论结果 | 跟踪人 | 备注 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | DC场景 | os下电升级过程中尝试给os上电影响os | 中等 | 中 | 实现上电锁禁止os上电 | 已讨论，需要实现 |  | |
| 2 | AC场景 | VRD上电升级完成后直接AC | 中等 | 中 | 上电升级缓存升级包，以及数据库。AC后下电触发生效 | 已讨论，需要实现 |  | |
| 3 | 数据获取异常状态 | 硬件通信异常导致升级失败 | 高 | 高 | 实现重试机制和超时处理 | 已讨论，需要实现 |  |  |

### 2.2.7 安全性分析

| 安全合规项 | 是否涉及 | 现有的防护措施 |
| --- | --- | --- |
| 访问控制（通道、文件权限、用户权限、查询权限、配置权限、接口权限） | 是 | 固件管理通用权限控制 |
| 敏感数据 | 否 | 不涉及敏感数据处理 |
| 日志（操作日志、维护日志、安全日志、运行日志） | 是 | 1. 记录所有升级操作日志<br>2. 记录升级失败和异常日志 |
| 文档 | 否 | 不涉及文档安全 |
| 加密及算法 | 否 | 不涉及加密算法 |
| 新增关键资源（密钥、证书、关键配置）备份、恢复 | 否 | 不涉及密钥证书管理 |
| 新增对外接口入参校验 | 否 | 不涉及 |
| 新增开源及三方软件引入 | 否 | 不涉及新的开源软件引入 |

# 3.功能实现
<!-- 通过表格、流程图、简明文字描述提供，力求容易看懂、容易实现，详细描述细节。 -->
## 3.1【功能编号】支持VRD固件独立升级功能实现

### 3.1.1 功能实现设计

新增类，用于独立VRD管理

```json
"VRDFirmware_xxx": {
    "UID":"String",                     // 天池架构使用，说明属于哪个单板
    "BoardType": "String",              // 天池架构使用，说明属于哪个单板
    "SoftwareId": "String",             // 固定格式用于展示
    "RefChip": "U8[]",                  // 升级关联chip
    "ChipType": "String",               // 芯片类型，指定加载升级步骤。
    // "VrdId":"String",                   根据id顺序排序,一个vrd配置一个
    // "ExpectFirmwareVersion": "U32",     // vrd预期版本
    // "RecoverChip": "U8[]",              // 恢复芯片
    // "UpdateFlag": "U8",                 // 说明是否已升过级，持久化
}
```

新增类，用于独立VRD管理

### 3.1.2 功能详细设计

#### 3.1.2.1 升级流程详细设计

**升级执行阶段流程：**

```mermaid
flowchart TD
    A[开始升级执行] --> B[获取芯片实例]
    B --> C[初始化通信通道]
    C --> D{初始化成功?}
    D -->|否| E[记录错误并返回]
    D -->|是| F[发送升级包]
    F --> G{发送成功?}
    G -->|否| H[重试发送]
    H --> I{重试次数超限?}
    I -->|是| J[记录错误并返回]
    I -->|否| F
    G -->|是| K[等待升级完成]
    K --> L{升级成功?}
    L -->|是| P[更新版本信息]
    L -->|否| R[返回升级失败]
    P --> Q[返回升级成功]
```

### 3.1.3 开发者测试

#### 3.1.3.1 单元测试

**测试用例设计：**

| 测试用例ID | 测试对象 | 输入条件 | 预期输出 | 测试覆盖 |
| --------- | ------- | ------- | ------- | ------- |
| UT001 | independent_vrd_service.new() | 有效bus和cfgs参数 | 成功创建实例 | 构造函数 |
| UT002 | independent_vrd_service.on_upgrade_prepare() | 有效升级参数 | 返回准备成功状态 | 升级准备 |
| UT003 | independent_vrd_service.on_upgrade_process() | 正常升级流程 | 返回升级成功状态 | 升级执行 |
| UT004 | vrd_upgrade_prepare() | 有效芯片参数 | 返回准备成功 | 芯片升级准备 |
| UT005 | upgrade_process() | 正常升级包 | 返回升级成功 | 芯片升级执行 |

**测试覆盖率目标：**

- 代码覆盖率：≥90%
- 分支覆盖率：≥85%
- 函数覆盖率：≥95%

#### 3.1.3.2 集成测试
<!-- IT，主要是组件/模块内的集成测试，测试对象是模块/组件接口。IT测试设计将模块/组件当作黑盒测试，IT测试用例中禁止对组件/模块内部代码打桩，如果确实有少量场景难以构造，可以考虑在测试框架中统一打桩并提供接口供测试用例调用构造场景。
说明：API测试属于IT，其测试对象是微服务接口。
PCST，是指PC上的服务集成测试，测试对象是功能需求。PCST测试设计，要覆盖正常功能、异常功能和交叉功能，采用灰盒 -->