当前在调试板卡SMC,在调试过程中需要对板卡SMC进行读写操作。之前在iBMC v2都是用testchip命令对SMC进行读写的,但是在openUBMC上并没有这个工具。openUBMC是如何对smc进行读写操作的?
答案内容由AI生成,仅供参考:
如何在 openUBMC 上对 SMC 进行直接读写操作
在 openUBMC 平台上,虽然没有传统 iBMC v2 中的 testchip 命令,但系统提供了更现代化、结构化的机制来实现对 SMC(System Management Controller) 的读写操作。这些机制基于 CSR(硬件自描述配置) 和 D-Bus 接口,结合专用调试工具(如 mdbctl),可以实现高效的 SMC 调试与访问。
openUBMC 中 SMC 读写的实现方式
openUBMC 通过 Accessor 和 Scanner 两类对象间接操作 SMC 寄存器,底层由 smc_interface.lua 等模块完成 SMC 协议通信。开发者可以通过以下方式直接或间接读写 SMC:
1. 使用 Accessor 对象进行按需读写
Accessor 类用于对不需要周期性读取、或需要执行写操作的硬件资源进行访问。对于 SMC 设备,它是读写的主要入口。
配置示例:
{
"Accessor_Adc4VccVlot": {
"Chip": "#/Smc_ExpBoardSMC",
"Offset": 4872,
"Size": 2,
"Mask": 65535,
"Type": 0,
"Value": 0
}
}
Chip:引用一个 SMC 对象(如Smc_ExpBoardSMC)。Offset:SMC 命令字(需转换为十进制)。Size:读取数据长度(字节)。Type:0:位读/写(配合 Mask)1:块读/写
Value:运行时返回/写入的值。
注意:JSON 不支持十六进制,
Offset必须转为十进制(如0x1230→4656)。
在 D-Bus 上读写
一旦配置完成,可通过 D-Bus 访问:
# 查看 Accessor 对象
busctl get-property xyz.openbmc_project.HwProxy /xyz/openbmc_project/HW/ACCESSOR_NAME xyz.openbmc_project.HW.Value Value
# 写入值
busctl set-property xyz.openbmc_projec...
2. 使用 Scanner 对象进行周期性监控
若需持续监控某个 SMC 寄存器状态,应使用 Scanner 配置周期性扫描。
配置示例:
{
"Scanner_FanPwrSensorStatus": {
"Chip": "#/Smc_ExpBoardSMC",
"Offset": 12544,
"Size": 2,
"Mask": 8,
"Period": 2000,
"Value": 0
}
}
Period:扫描周期(单位 ms),如2000表示每 2 秒读一次。- 数据会自动更新至 BMC 资源树中。
3. 使用 mdbctl 工具直接调试读写
尽管 openUBMC 不提供 testchip,但可通过调试工具 mdbctl 实现类似功能。
启用调试模式并连接硬件代理模块:
# 进入 mdbctl
mdbctl
# 查看可用类
lsclass | grep -i smc
# 查看 SMC 相关对象
lssclass hwproxy | grep Smc
# 列出所有 Smc 对象实例
lsobject Smc
跟踪 SMC 器件读写行为
# 开始追踪某 SMC 器件的读写
tracechip Smc_ExpBoardSMC start
# 停止追踪
tracechip Smc_ExpBoardSMC stop
查看寄存器值(间接)
通过已定义的 Accessor 或 Scanner 获取数据:
getprop Accessor_Adc4VccVlot Value
4. 通过脚本调用 smc_interface.lua 接口
smc_interface.lua 是底层 Lua 模块,负责封装 SMC 通信协议(基于 I2C/SMBus)。该模块支持读取 VRD Dump、DFX Info 等信息。
典型操作包括:
SMC read (vrd dump len)→ 读取电压调节器配置SMC read (get dfx info)→ 获取调试信息
实际使用中发现该模块常因 “unsupported opcode” 导致读取失败(如
Smc_CpuBrdSMC_0101芯片),这通常意味着固件版本不兼容或命令未被支持。
可通过修改 CSR 配置中的 Offset(即 SMC 命令字) 来指定具体操作。
推荐调试流程
| 步骤 | 操作 |
|---|---|
| 1 | 确认目标 SMC 设备对象名称(如 Smc_ExpBoardSMC_0101) |
| 2 | 在 CSR 中定义 Accessor,设置正确的 Chip, Offset, Size |
| 3 | 重启 hwproxy 服务加载配置 |
| 4 | 使用 mdbctl 或 D-Bus 命令读写 Value 属性测试 |
| 5 | 使用 tracechip 跟踪实际 I2C 通信过程 |
| 6 | 分析日志中是否有 unsupported opcode 等错误 |
常见问题及解决建议
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
读取失败,提示 unsupported opcode |
SMC 固件不支持该命令字 | 检查命令字是否符合 SMC 规范;升级 SMC 固件 |
Smc_ExpBoardSMC_0101 创建失败 |
配置错误或芯片不被识别 | 确保 Address、AddrWidth 正确,检查 I2C 连接 |
| Offset 显示异常 | 使用了十六进制而非十进制 | 将所有 Offset 转换为十进制值 |
| 写操作无效 | 设备不支持写入 | 确认硬件文档是否允许写入该寄存器 |
相关文档参考
- [CSR配置字典之Accessor类]
定义了如何通过Accessor访问 SMC。 - [CSR配置字典之Smc类]
定义了Smc对象的基本属性(Address,AddrWidth,OffsetWidth)。 - 《硬件自描述文件(CSR)》
说明了#/语法用于对象引用机制。 - 《general_hardware》架构文档
展示了smc_interface.lua的位置与作用。
总结
| 功能 | 实现方式 |
|---|---|
| SMC 读操作 | 使用 Accessor + D-Bus 或 Scanner 周期扫描 |
| SMC 写操作 | 使用 Accessor 的 Value 属性写入 |
| 调试追踪 | 使用 mdbctl tracechip 命令 |
| 协议支持 | 由 smc_interface.lua 模块处理 |
| 配置管理 | 通过 CSR 文件定义 Smc 与 Accessor 对象 |
openUBMC 虽移除了 testchip 这类低层工具,但通过 结构化配置 和 D-Bus 接口 实现了更安全、可维护的硬件访问机制。推荐使用 Accessor 结合 mdbctl 进行调试,这是最接近 testchip 功能的替代方案。
相关链接:
mdbctl call 这种形式, 注意存在位读/写(BitIO), 块读/写两种方式(BlockIO),建议优先使用BlockIO方式进行读写操作
能给一个示例吗,mdbctl call如何读写smc?
mdbctl call Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BlockIO Write 0 0x8008a01 1 0x01
这个就是通过BlockIO方式 往偏移地址 0x8008a01处 写入值 0x1
感谢