背景
鲲鹏/昇腾新增CPLD无感升级场景,允许CPLD在正常运行过程中上传固件包,执行升级操作并立即生效。为确保CPLD业务功能不受影响,无感升级流程中BMC与CPLD需要通信配合,提前告知CPLD消费模块即将开始无感升级,同时BMC需要负责CPLD升级完成后的关键寄存器内容恢复。为实现以上功能点,需要在LogicFirmware对象内新增若干属性,用于描述CPLD在无感升级过程中需要使用到的信息。
关联ISSUE
整体方案
- 硬件提供hpm包时在update.cfg文件中新增属性HotValidType,执行升级流程时,general_hardware组件判断若HotValidType = 1,则执行无感升级流程,否则执行现有的冷升级流程。
- 完整的无感升级流程,步骤如下:
- 向CPLD中写入cpld.svf文件。
- 检查bios是否处于正在启动的状态,如果是的话等待bios启动完成。之后向CPLD寄存器写入标志位,通知CPLD将数据存储到flash,并等待CPLD通过寄存器响应。
- 将CPLD指定的寄存器列表里面的数据读出,保存下来,待升级流程完成后重新写入进行恢复。
- 向CPLD寄存器写入标志位,通知其他CPLD消费模块即将开始升级,需要暂停访问CPLD的操作。等待各消费模块做好升级准备后写寄存器回复BMC。
- 关闭BMC访问CPLD的能力,防止升级过程中产生误告警。
- 拉低无感升级专用GPIO。
- 加载valid.svf文件。
- 恢复步骤3)、4)、5)、6)的操作。
- 以上无感升级流程中,并非所有的步骤都要执行,而是根据具体产品的CPLD执行其中一部分。例如,鲲鹏产品的CPLD无感升级时,无需执行步骤4)、6);昇腾产品的CPLD无感升级时,无需执行步骤2)。此外,以上步骤中与CPLD通信交互的寄存器地址、需要保存与恢复的寄存器地址、GPIO管脚编号等信息均与具体的CPLD相关,无法固化在代码流程中。因此,需要为LogicFirmware对象新增私有属性,关联以上无感升级流程中的必要信息。在配置CSR时正确配置LogicFirmware的这些新增属性,从而实现无感升级功能的正确执行。
评审点
评审点1:新增对象CpldRestoreReg,用于无感升级流程中保存和恢复寄存器内容
评审点2:LogicFirmware对象新增私有属性WriteSignalReg,用于无感升级过程中BMC通知消费模块即将开始无感升级
评审点3:新增对象CpldReadSignalReg,用于无感升级过程中各个消费模块通知BMC已完成无感升级的准备
评审点4:LogicFirmware对象新增私有属性UpgradeGpioIndex,用于保存无感升级使用的GPIO管脚信息
评审点5:LogicFirmware对象新增私有属性HotUpgradeFailedProcess,用于决定无感升级流程失败时是否自动回退到冷升级
评审点6:LogicFirmware对象新增私有属性HotUpgradeSupport,用于判断待升级CPLD逻辑是否支持无感升级功能
评审点7:LogicFirmware对象新增私有属性PrepareHotUpgrade,用于判断待升级CPLD逻辑需要执行的前置操作
详细描述
评审点1:新增对象CpldRestoreReg,用于无感升级流程中保存和恢复寄存器内容
| 属性名称 | 涉及对象 | 资源path | 变化类型 | 属性说明 | 持久化类型 | 取值说明 |
|---|---|---|---|---|---|---|
| RestoreReg | general_hardware组件的CpldRestoreReg对象 | 无 | 新增私有属性 | 待保存与恢复的寄存器对象 | 不持久化 | 关联Accessor寄存器对象 |
| RestoreType | general_hardware组件的CpldRestoreReg对象 | 无 | 新增私有属性 | 无感升级后寄存器值的恢复策略 | 不持久化 | 0:RestoreValueState正常时使用RestoreValue恢复,否则使用RestoreDefaultValue恢复 1:RestoreValueState正常时使用RestoreValue恢复,否则无动作 其他值:不处理 默认值:0 |
| RestoreValue | general_hardware组件的CpldRestoreReg对象 | 无 | 新增私有属性 | 待保存与恢复的寄存器值 | 不持久化 | 1. 配置为固定值,表示升级完成后需要将该寄存器恢复为固定值 2. 配置为关联Accessor或Scanner,表示升级前需要读取寄存器内容保存,升级后根据读取的内容恢复 |
| RestoreValueState | general_hardware组件的CpldRestoreReg对象 | 无 | 新增私有属性 | 待保存与恢复的寄存器值状态 | 不持久化 | 0:寄存器值正常,无感升级后使用RestoreValue进行恢复 非0:寄存器值异常,无感升级后的恢复动作根据RestoreType取值决定 默认值:0 |
| RestoreDefaultValue | general_hardware组件的CpldRestoreReg对象 | 无 | 新增私有属性 | 当RestoreValueState异常时需要恢复的默认值 | 不持久化 | 配置为固定值,当RestoreValueState异常且需要恢复时,使用该值恢复 |
| RefLogicFirmware | general_hardware组件的CpldRestoreReg对象 | 无 | 新增私有属性 | 该对象关联的LogicFirmware对象 | 不持久化 | 关联LogicFirmware对象 |
配置举例:
"LogicFirmware_Test1": {
...
"Name": "XXX_CPLD1",
...
},
"CpldRestoreReg_Test1": {
"RestoreReg": "#/Accessor_Reg1.Value",
"RestoreValue": 5,
"RefLogicFirmware": "#/LogicFirmware_Test1"
},
"CpldRestoreReg_Test2": {
"RestoreReg": "#/Accessor_Reg2.Value",
"RestoreValue": "<=/Scanner_Reg2.Value",
"RestoreValueState": "<=/Scanner_Reg2.State",
"RestoreDefaultValue": 10,
"RefLogicFirmware": "#/LogicFirmware_Test1"
},
"CpldRestoreReg_Test3": {
"RestoreReg": "#/Accessor_Reg3.Value",
"RestoreValue": "<=/Scanner_Reg3.Value",
"RestoreValueState": "<=/Scanner_Reg3.State",
"RestoreType": 1,
"RefLogicFirmware": "#/LogicFirmware_Test1"
}
以上配置含义中,各寄存器的恢复策略如下:
- Reg1:无感升级后恢复为默认值5
- Reg2:如果升级前自身的State正常,则保存自身数值,无感升级后恢复为保存的数值。否则恢复为默认值10
- Reg3:如果升级前自身的State正常,则保存自身数值,无感升级后恢复为保存的数值。否则不恢复
评审点2:LogicFirmware对象新增私有属性WriteSignalReg,用于无感升级过程中BMC通知消费模块即将开始无感升级
| 属性名称 | 涉及对象 | 资源path | 变化类型 | 属性说明 | 持久化类型 | 取值说明 |
|---|---|---|---|---|---|---|
| WriteSignalReg | general_hardware组件的LogicFirmware对象 | 无 | 新增私有属性 | 关联待升级CPLD的寄存器,用于在无感升级前通知其他消费模块准备升级 | 不持久化 | 关联待升级CPLD的寄存器 |
配置举例:
"LogicFirmware_Test1": {
...
"WriteSignalReg": "#/Accessor_Reg4.Value",
...
}
评审点3:新增对象CpldReadSignalReg,用于无感升级过程中各个消费模块通知BMC已完成无感升级的准备
| 属性名称 | 涉及对象 | 资源path | 变化类型 | 属性说明 | 持久化类型 | 取值说明 |
|---|---|---|---|---|---|---|
| Reg | general_hardware组件的CpldReadSignalReg对象 | 无 | 新增私有属性 | BMC接收各消费模块已准备好进行升级的寄存器 | 不持久化 | 关联Accessor寄存器对象 |
| RefLogicFirmware | general_hardware组件的CpldReadSignalReg对象 | 无 | 新增私有属性 | 该对象关联的LogicFirmware对象 | 不持久化 | 关联LogicFirmware对象 |
配置举例:
"LogicFirmware_Test1": {
...
"Name": "XXX_CPLD1",
...
},
"CpldReadSignalReg_Test1": {
"Reg": "#/Accessor_Reg5.Value",
"RefLogicFirmware": "#/LogicFirmware_Test1"
},
"CpldReadSignalReg_Test2": {
"Reg": "#/Accessor_Reg6.Value",
"RefLogicFirmware": "#/LogicFirmware_Test1"
},
"CpldReadSignalReg_Test3": {
"Reg": "#/Accessor_Reg7.Value",
"RefLogicFirmware": "#/LogicFirmware_Test1"
}
以上评审点2和3中新增的属性具体使用方法如下:
sequenceDiagram
participant BMC as BMC
participant CPLD as CPLD
participant model1 as 消费模块1
participant model2 as 消费模块2
participant modeln as 消费模块n
Note over BMC: 无感升级步骤1)、2)、3)
BMC ->> CPLD: 将WriteSignalReg寄存器写为0
Note over CPLD: 逻辑保证,每当WriteSignalReg寄存器跳变时,自动将所有的ReadSignalRegs写为0
BMC ->> CPLD: 将WriteSignalReg寄存器写为0x55
BMC -->> CPLD: 循环读取所有ReadSignalRegs,等待寄存器全变为0x55
model1 -->> CPLD: 读取WriteSignalReg变为0x55
model2 -->> CPLD: 读取WriteSignalReg变为0x55
modeln -->> CPLD: 读取WriteSignalReg变为0x55
Note over model1: 升级前准备工作
Note over model2: 升级前准备工作
Note over modeln: 升级前准备工作
model1 ->> CPLD: 写ReadSignalReg为0x55
model2 ->> CPLD: 写ReadSignalReg为0x55
modeln ->> CPLD: 写ReadSignalReg为0x55
BMC -->> CPLD: 所有ReadSignalReg已变为0x55
Note over BMC: 无感升级步骤5)、6)、7)
BMC ->> CPLD: 将WriteSignalReg寄存器写为0
BMC ->> CPLD: 将WriteSignalReg寄存器写为0xAA
BMC -->> CPLD: 循环读取所有ReadSignalRegs,等待寄存器全变为0xAA
model1 -->> CPLD: 读取WriteSignalReg变为0xAA
model2 -->> CPLD: 读取WriteSignalReg变为0xAA
modeln -->> CPLD: 读取WriteSignalReg变为0xAA
Note over model1: 升级后恢复工作
Note over model2: 升级后恢复工作
Note over modeln: 升级后恢复工作
model1 ->> CPLD: 写ReadSignalReg为0xAA
model2 ->> CPLD: 写ReadSignalReg为0xAA
modeln ->> CPLD: 写ReadSignalReg为0xAA
BMC ->> CPLD: 将WriteSignalReg寄存器写为0
Note over BMC: 无感升级剩余步骤
评审点4:LogicFirmware对象新增私有属性UpgradeGpioIndex,用于保存无感升级使用的GPIO管脚信息
| 属性名称 | 涉及对象 | 资源path | 变化类型 | 属性说明 | 持久化类型 | 取值说明 |
|---|---|---|---|---|---|---|
| UpgradeGpioIndex | general_hardware组件的LogicFirmware对象 | 无 | 新增私有属性 | 无感升级流程中使用的专用GPIO引脚编号 | 不持久化 | 取值为U8,GPIO引脚编号 默认值:255 |
配置举例:
"LogicFirmware_Test1": {
...
"UpgradeGpioIndex": 55,
...
}
评审点5:LogicFirmware对象新增私有属性HotUpgradeFailedProcess,用于决定无感升级流程失败时是否自动回退到冷升级
| 属性名称 | 涉及对象 | 资源path | 变化类型 | 属性说明 | 持久化类型 | 取值说明 |
|---|---|---|---|---|---|---|
| HotUpgradeFailedProcess | general_hardware组件的LogicFirmware对象 | 无 | 新增私有属性 | 无感升级流程中如果报错退出,是否需要自动回退至冷升级流程 | 不持久化 | 取值为U8,0:无感升级失败时报错退出;1:无感升级失败时回退至冷升级;其他值:无感升级失败时报错退出 默认值:0 |
配置举例:
"LogicFirmware_Test1": {
...
"HotUpgradeFailedProcess": 1,
...
}
需要注意的时,该配置属性只影响升级步骤3)、4)、5)中发生失败时的处理方式。如果其他步骤发生失败,则固定返回升级失败结果。
评审点6:LogicFirmware对象新增私有属性HotUpgradeSupport,用于判断待升级CPLD逻辑是否支持无感升级功能
| 属性名称 | 涉及对象 | 资源path | 变化类型 | 属性说明 | 持久化类型 | 取值说明 |
|---|---|---|---|---|---|---|
| HotUpgradeSupport | general_hardware组件的LogicFirmware对象 | 无 | 新增私有属性 | 关联CPLD寄存器,表示当前CPLD逻辑是否支持无感升级 | 不持久化 | 取值为U8,关联CPLD寄存器。0:不支持无感升级;1:支持无感升级;其他值:不支持无感升级 默认值:0 |
配置举例:
"LogicFirmware_Test1": {
...
"HotUpgradeSupport": 1,
...
}
评审点7:LogicFirmware对象新增私有属性PrepareHotUpgrade,用于判断待升级CPLD逻辑是否需要前置操作
| 属性名称 | 涉及对象 | 资源path | 变化类型 | 属性说明 | 持久化类型 | 取值说明 |
|---|---|---|---|---|---|---|
| PrepareHotUpgrade | general_hardware组件的LogicFirmware对象 | 无 | 新增私有属性 | 当前CPLD执行无感升级时所需的前置处理 | 不持久化 | 取值为String[ ],数组中的每个字符串表示一个需要执行的前置操作。当前支持字符串:WaitBiosStart,表示需要等待bios启动完成 默认值:空 |
配置举例:
"LogicFirmware_Test1": {
...
"PrepareHotUpgrade": [
"WaitBiosStart"
]
...
}
评审结论
- 同意新增对象CpldRestoreReg,该新增对象包含私有属性RestoreReg、RestoreType、RestoreValue、RestoreValueState、RestoreDefaultValue、RefLogicFirmware,用于无感升级流程中保存和恢复寄存器内容
- 同意LogicFirmware对象下新增私有属性WriteSignalReg,用于BMC写入,通知其他消费模块即将开始无感升级
- 同意新增对象CpldReadSignalReg,该新增对象包含私有属性Reg、RefLogicFirmware,用于消费模块写入,BMC读取,消费模块借此向BMC通知已准备好进行无感升级
- 同意LogicFirmware对象下新增私有属性UpgradeGpioIndex,用于无感升级过程中操作专用GPIO。
- 同意LogicFirmware对象下新增私有属性HotUpgradeFailedProcess,用于决定无感升级流程失败时是否自动回退到冷升级
- 同意LogicFirmware对象下新增私有属性HotUpgradeSupport,用于判断待升级CPLD逻辑是否支持无感升级功能
- 同意LogicFirmware对象新增私有属性PrepareHotUpgrade,用于判断待升级CPLD逻辑需要执行的前置操作
遗留问题
- 评审点1、3中的RefLogicFirmware属性,具体配置方法由LogicFirmware的Name修改为直接关联对应的LogicFirmware:已修改。
- 评审点4中的UpgradeGpio属性命名修改为UpgradeGpioIndex:已修改。
- 评审点1中的RestoreValue属性,需要向框架确认是否有锁定scanner读取值的方法:待确认,如果有此类方法,则在组件代码中进行适配。