如何直接读写SMC

当前在调试板卡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 调试与访问。


:wrench: openUBMC 中 SMC 读写的实现方式

openUBMC 通过 AccessorScanner 两类对象间接操作 SMC 寄存器,底层由 smc_interface.lua 等模块完成 SMC 协议通信。开发者可以通过以下方式直接或间接读写 SMC:

1. 使用 Accessor 对象进行按需读写

Accessor 类用于对不需要周期性读取、或需要执行写操作的硬件资源进行访问。对于 SMC 设备,它是读写的主要入口。

:white_check_mark: 配置示例:

{
  "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:运行时返回/写入的值。

:pushpin: 注意:JSON 不支持十六进制,Offset 必须转为十进制(如 0x12304656)。

:magnifying_glass_tilted_left: 在 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 配置周期性扫描。

:white_check_mark: 配置示例:

{
  "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 实现类似功能。

:white_check_mark: 启用调试模式并连接硬件代理模块:

# 进入 mdbctl
mdbctl

# 查看可用类
lsclass | grep -i smc

# 查看 SMC 相关对象
lssclass hwproxy | grep Smc

# 列出所有 Smc 对象实例
lsobject Smc

:white_check_mark: 跟踪 SMC 器件读写行为

# 开始追踪某 SMC 器件的读写
tracechip Smc_ExpBoardSMC start

# 停止追踪
tracechip Smc_ExpBoardSMC stop

:white_check_mark: 查看寄存器值(间接)

通过已定义的 AccessorScanner 获取数据:

getprop Accessor_Adc4VccVlot Value

4. 通过脚本调用 smc_interface.lua 接口

smc_interface.lua 是底层 Lua 模块,负责封装 SMC 通信协议(基于 I2C/SMBus)。该模块支持读取 VRD DumpDFX Info 等信息。

典型操作包括:

  • SMC read (vrd dump len) → 读取电压调节器配置
  • SMC read (get dfx info) → 获取调试信息

:warning: 实际使用中发现该模块常因 “unsupported opcode” 导致读取失败(如 Smc_CpuBrdSMC_0101 芯片),这通常意味着固件版本不兼容或命令未被支持。

可通过修改 CSR 配置中的 Offset(即 SMC 命令字) 来指定具体操作。


:hammer_and_wrench: 推荐调试流程

步骤 操作
1 确认目标 SMC 设备对象名称(如 Smc_ExpBoardSMC_0101
2 在 CSR 中定义 Accessor,设置正确的 Chip, Offset, Size
3 重启 hwproxy 服务加载配置
4 使用 mdbctl 或 D-Bus 命令读写 Value 属性测试
5 使用 tracechip 跟踪实际 I2C 通信过程
6 分析日志中是否有 unsupported opcode 等错误

:red_exclamation_mark: 常见问题及解决建议

问题 可能原因 解决方案
读取失败,提示 unsupported opcode SMC 固件不支持该命令字 检查命令字是否符合 SMC 规范;升级 SMC 固件
Smc_ExpBoardSMC_0101 创建失败 配置错误或芯片不被识别 确保 AddressAddrWidth 正确,检查 I2C 连接
Offset 显示异常 使用了十六进制而非十进制 将所有 Offset 转换为十进制值
写操作无效 设备不支持写入 确认硬件文档是否允许写入该寄存器

:books: 相关文档参考

  1. [CSR配置字典之Accessor类]
    定义了如何通过 Accessor 访问 SMC。
  2. [CSR配置字典之Smc类]
    定义了 Smc 对象的基本属性(Address, AddrWidth, OffsetWidth)。
  3. 《硬件自描述文件(CSR)》
    说明了 #/ 语法用于对象引用机制。
  4. 《general_hardware》架构文档
    展示了 smc_interface.lua 的位置与作用。

:white_check_mark: 总结

功能 实现方式
SMC 读操作 使用 Accessor + D-Bus 或 Scanner 周期扫描
SMC 写操作 使用 AccessorValue 属性写入
调试追踪 使用 mdbctl tracechip 命令
协议支持 smc_interface.lua 模块处理
配置管理 通过 CSR 文件定义 SmcAccessor 对象

openUBMC 虽移除了 testchip 这类低层工具,但通过 结构化配置D-Bus 接口 实现了更安全、可维护的硬件访问机制。推荐使用 Accessor 结合 mdbctl 进行调试,这是最接近 testchip 功能的替代方案。

相关链接:

  1. 怎样使用smbus的命令发送smc命令字
  2. 【iTestSmart OpenUBMC问题反馈】IPMI普通用户权限管理,测试结果Fail。
  3. 关于CPLD升级分析遇到的一些问题
  4. Accessor/Scanner获取value失败
  5. CSR配置字典之Accessor类 | 文档中心 | openUBMC

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

感谢