Accessor无法修改EEPROM写保护状态

问题描述

1 写EXU的FRU失败
2 通过SMC指令手动关闭EEPROM写保护,FRU写入成功

~ ~ # tail -f /var/log/app.log | grep fru
2026-04-09 18:16:33.579081 alarm NOTICE: l_frudata_intf.c(94): [frudata] fru(0) ipmi write area(2) filed(2) data(abc)
2026-04-09 18:16:33.579705 frudata NOTICE: fru_ipmi.lua(194): Write fru0 E-lable data(RAW:00-02-02-00-03-61-62-63) successfully
2026-04-09 18:16:33.580480 frudata NOTICE: frudata_app.lua(298): write_fru_data_sig: Fru_id = 0.
2026-04-09 18:16:33.645453 frudata NOTICE: manage.lua(301): write fru area to eep start: fru_id = 0, FruOffset = 128, EepromWp_state = 1
2026-04-09 18:16:33.696823 frudata ERROR: frudata_service.lua(147): write_fru_area failed. fru_id = 0, ret=BMC.Error.Unknow: ./opt/bmc/libmc/lualib/mc/context.lua:203: ./opt/bmc/libmc/lualib/sd_bus/object.lua:317: ./opt/bmc/apps/hwproxy/lualib/hwproxy_objects/app_bus.lua:104: ./opt/bmc/apps/hwproxy/lualib/hw_utils/hw_wait_access.lua:101: chip: Eeprom_EXU_0101, bus: I2c_2, write failed: i2c.lua:117: response error, i2c write fail, ret: 5, input:{"len":32,"name":"Eeprom_EXU_0101","buffer":"01 00 01 02 07 00 00 F5 01 01 00 C0 C0 C1 00 BD \n01 05 00 00 00 00 C6 48 75 61 77 65 69 C3 61 62 \n","offsetWidth":2,"addrWidth":1,"addr":174,"offset":128,"mask":4294967295,"rw_type":0,"type":1,"has_error":false,"is_trace":false,"requestor":"bmc.kepler.frudata"}




^C
~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Write a{ss}uyuay 0 134239744 1 255 1 0
~ ~ # 
~ ~ # tail -f /var/log/app.log | grep fru
2026-04-09 18:16:33.579081 alarm NOTICE: l_frudata_intf.c(94): [frudata] fru(0) ipmi write area(2) filed(2) data(abc)
2026-04-09 18:16:33.579705 frudata NOTICE: fru_ipmi.lua(194): Write fru0 E-lable data(RAW:00-02-02-00-03-61-62-63) successfully
2026-04-09 18:16:33.580480 frudata NOTICE: frudata_app.lua(298): write_fru_data_sig: Fru_id = 0.
2026-04-09 18:16:33.645453 frudata NOTICE: manage.lua(301): write fru area to eep start: fru_id = 0, FruOffset = 128, EepromWp_state = 1
2026-04-09 18:16:33.696823 frudata ERROR: frudata_service.lua(147): write_fru_area failed. fru_id = 0, ret=BMC.Error.Unknow: ./opt/bmc/libmc/lualib/mc/context.lua:203: ./opt/bmc/libmc/lualib/sd_bus/object.lua:317: ./opt/bmc/apps/hwproxy/lualib/hwproxy_objects/app_bus.lua:104: ./opt/bmc/apps/hwproxy/lualib/hw_utils/hw_wait_access.lua:101: chip: Eeprom_EXU_0101, bus: I2c_2, write failed: i2c.lua:117: response error, i2c write fail, ret: 5, input:{"len":32,"name":"Eeprom_EXU_0101","buffer":"01 00 01 02 07 00 00 F5 01 01 00 C0 C0 C1 00 BD \n01 05 00 00 00 00 C6 48 75 61 77 65 69 C3 61 62 \n","offsetWidth":2,"addrWidth":1,"addr":174,"offset":128,"mask":4294967295,"rw_type":0,"type":1,"has_error":false,"is_trace":false,"requestor":"bmc.kepler.frudata"}


2026-04-09 18:17:15.646117 alarm NOTICE: l_frudata_intf.c(94): [frudata] fru(0) ipmi write area(2) filed(2) data(abc)
2026-04-09 18:17:15.646817 frudata NOTICE: fru_ipmi.lua(194): Write fru0 E-lable data(RAW:00-02-02-00-03-61-62-63) successfully
2026-04-09 18:17:15.647449 frudata NOTICE: frudata_app.lua(298): write_fru_data_sig: Fru_id = 0.
2026-04-09 18:17:15.706785 frudata NOTICE: manage.lua(301): write fru area to eep start: fru_id = 0, FruOffset = 128, EepromWp_state = 0
2026-04-09 18:17:17.299538 frudata NOTICE: manage.lua(306): write fru area to eep end: fru_id = 0, data = [Huaweiabc25.12.02.03 HuaweiSK90-1U1Nwuhansk901u1n1234432125.12.02.03]

CSR配置

        "Eeprom_EXU": {
            "OffsetWidth": 2,
            "AddrWidth": 1,
            "Address": 174,
            "WriteTmout": 100,
            "ReadTmout": 100,
            "RwBlockSize": 32,
            "WriteInterval": 20,
            "HealthStatus": 0
        },
        "Accessor_EXUWP": {
            "Chip": "#/Smc_ExpBoardSMC",
            "Size": 1,
            "Offset": 134239488,
            "Mask": 255,
            "Type": 0,
            "Value": 0
        },
        "FruData_Expander": {
            "FruId": 0,
            "FruDev": "#/Eeprom_EXU",
            "EepromWp": "#/Accessor_EXUWP.Value",
            "BoardSerialNumber": "",
            "StorageType": "TianChi"
        },

环境信息

  • 软件版本:OpenUBMC2512

答案内容由AI生成,仅供参考:

:pushpin: 五、总结

项目 结论
问题本质 Accessor未能正确关闭EEPROM写保护,导致I2C写入失败
根本原因 Accessor_EXUWP配置的Offset与实际SMC寄存器地址不符,导致写保护控制失效
验证方式 手动使用正确Offset可成功写入,证明硬件正常
解决方案 1. 修正Accessor_EXUWP.Offset134239744
2. 验证frudata是否调用Accessor
3. 增加日志跟踪写保护状态
4. 必要时使用SMC命令绕过Accessor
建议改进 在CSR配置文档中明确SMC寄存器映射与Accessor配置对应关系,避免偏移错误

:white_check_mark: 结论:
修正Accessor_EXUWPOffset字段为134239744,并验证frudata是否成功调用该Accessor,即可解决本问题。

点击此处查看详细分析解答

Accessor无法修改EEPROM写保护状态问题分析报告

根据提供的日志、配置信息及系统行为,以下是对“Accessor无法修改EEPROM写保护状态”导致FRU写入失败的全面分析与解决方案建议。


:magnifying_glass_tilted_left: 一、问题描述

用户在尝试通过IPMI命令写入FRU数据(fru_id = 0)时,写操作失败,但通过SMC指令手动关闭EEPROM写保护后,写入成功
主要现象如下:

  • 日志显示 write fruid(0) eeprom failed,错误码为 BMC.Error.Unknown
  • 关键错误信息:i2c write fail, ret: 5,表明I2C写入EEPROM失败。
  • 失败时 EepromWp_state = 1(即写保护状态为开启)。
  • 手动调用Smc_ExpBoardSMC_0101BitIO Write命令关闭写保护后,再次写入成功且日志显示 EepromWp_state = 0

:puzzle_piece: 二、根本原因分析

1. 写保护机制未生效

尽管CSR配置中已定义:

"FruData_Expander": {
    "EepromWp": "#/Accessor_EXUWP.Value"
}

表示应通过 Accessor_EXUWP 控制EEPROM写保护,但实际写入过程中,该Accessor未能正确关闭写保护,导致EEPROM处于只读状态,无法完成写入。


2. Accessor_EXUWP 配置与执行脱节

  • Accessor_EXUWP 配置如下:
    "Accessor_EXUWP": {
        "Chip": "#/Smc_ExpBoardSMC",
        "Size": 1,
        "Offset": 134239488,
        "Mask": 255,
        "Type": 0,
        "Value": 0
    }
    
  • 表明其通过SMC芯片(Smc_ExpBoardSMC)的特定偏移地址控制写保护。
  • 但在frudata写入流程中,日志显示:
    write fru area to eep start: fru_id = 0, FruOffset = 128, EepromWp_state = 1
    
    说明系统认为写保护仍处于开启状态(EepromWp_state = 1

:pushpin: 推论:
frudata服务在尝试写入前,未能成功通过Accessor_EXUWP关闭写保护,即Accessor的Write操作未生效或被忽略。


3. 手动SMC指令可成功,证明硬件链路正常

执行以下命令手动关闭写保护:

busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Write a{ss}uyuay 0 134239744 1 255 1 0

随后写入成功,说明:

  • 硬件I2C通信正常
  • EEPROM本身可写
  • 写保护是软件逻辑问题,而非硬件故障

:white_check_mark: 因此,根本原因在于:Accessor未能在FRU写入前正确触发写保护关闭操作


4. 可能的深层原因

可能原因 分析
Accessor对象未正确注册或未被frudata调用 frudata可能未按CSR配置调用Accessor_EXUWP.Value进行写保护控制。
Accessor写操作失败但未报错 hwproxy执行写Accessor时失败,但frudata未捕获或忽略了该错误。
Offset或Chip配置错误 Offset: 134239488 可能与实际SMC寄存器地址不符(特别是与手动使用的134239744不一致)。
Accessor类型不匹配 Type: 0 表示为GPIO-style控制,但SMC可能需要BitIO或其他接口,导致写入无效。

:warning: 特别注意:
手动命令使用 Offset: 134239744,而配置中为 134239488 —— 相差256字节,极可能是配置错误


:bar_chart: 三、相关实体与关系梳理(基于知识图谱)

实体 说明
Eeprom_EXU_0101 目标EEPROM设备,位于I2c_2总线,写入失败。
Eeprom_EXU EEPROM配置,定义了AddrWidth, OffsetWidth, WriteTmout等参数。
FruData_Expander 使用Eeprom_EXU作为存储介质,通过Accessor_EXUWP.Value控制写保护。
Accessor_EXUWP 本应控制写保护,但未能生效。
Smc_ExpBoardSMC_0101 实际控制写保护的SMC芯片,手动操作成功。
frudata 负责FRU数据写入的服务,日志中显示未成功修改EepromWp_state

:white_check_mark: 关系链:

frudata → FruData_Expander → EepromWp=#/Accessor_EXUWP.Value → Accessor_EXUWP → Smc_ExpBoardSMC

当前断点在Accessor_EXUWP到SMC的控制链


:white_check_mark: 四、解决方案建议

1. 核查并修正Accessor配置偏移地址

  • 问题: 配置中Accessor_EXUWP.Offset = 134239488,但手动成功使用的地址为134239744(差256)。
  • 建议:
    检查SMC寄存器映射表,确认正确的写保护控制位偏移地址,Offset修改为134239744
"Accessor_EXUWP": {
    "Chip": "#/Smc_ExpBoardSMC",
    "Size": 1,
    "Offset": 134239744,  // ✅ 修改为手动成功使用的地址
    "Mask": 255,
    "Type": 0,
    "Value": 0
}

2. 验证Accessor是否被正确调用

  • 检查frudata服务是否在写入前调用了Accessor_EXUWP
  • 查看日志中是否有关于Accessor操作的记录,例如:
    • set eeprom write protect = 0
    • write accessor EXUWP succeeded
  • 若无,则需确认CSR配置是否被正确解析,或frudata代码逻辑是否跳过了写保护控制。

3. 增加日志与调试信息

  • frudata_service.lua中,于写入EEPROM前,显式记录EepromWp的状态变化
  • 添加调试输出,确认是否执行了Accessor的写操作。

示例逻辑:

log.info("Setting EepromWp to 0")
local ret = accessor:set_value(0)
if ret ~= 0 then
    log.error("Failed to disable write protect")
end

4. 考虑写保护控制方式(BitIO vs GPIO)

  • 当前Type: 0 表示GPIO风格控制。
  • 若SMC芯片需通过BitIO接口控制,应确保:
    • Smc_ExpBoardSMC支持BitIO
    • Accessor应配置为调用BitIO.Write而非普通写
  • 或直接在FruData_Expander中通过PreWriteHook执行SMC命令。

5. 临时规避方案

若无法立即修复Accessor,可临时通过以下方式绕过:

  • 在写FRU前,由脚本主动调用SMC命令关闭写保护
    busctl call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Write a{ss}uyuay 0 134239744 1 255 1 0
    
  • 写入完成后重新开启保护。

:pushpin: 五、总结

项目 结论
问题本质 Accessor未能正确关闭EEPROM写保护,导致I2C写入失败
根本原因 Accessor_EXUWP配置的Offset与实际SMC寄存器地址不符,导致写保护控制失效
验证方式 手动使用正确Offset可成功写入,证明硬件正常
解决方案 1. 修正Accessor_EXUWP.Offset134239744
2. 验证frudata是否调用Accessor
3. 增加日志跟踪写保护状态
4. 必要时使用SMC命令绕过Accessor
建议改进 在CSR配置文档中明确SMC寄存器映射与Accessor配置对应关系,避免偏移错误

:paperclip: 附注:

  • 参考知识库用户 adellonzzy 的经验,其曾指出类似问题,强调需精确匹配I2C地址与寄存器偏移
  • frudata 是开源组件(华为Mulan PSL v2),可审查其manage.lua中写保护控制逻辑。

:white_check_mark: 结论:
修正Accessor_EXUWPOffset字段为134239744,并验证frudata是否成功调用该Accessor,即可解决本问题。

有尝试通过直接设置Accessor的Value可以修改写保护吗?使用的命令是setprop set还是setprop modify?

通过Accessor修改没有效果。

~ ~ # mdbctl lsprop Accessor_EXUWP_0101
bmc.kepler.Accessor
  Status=0
  Value=1
bmc.kepler.Object.Properties
  ClassName="Accessor"
  ObjectIdentifier=[1,"1","1","0101"]
  ObjectName="Accessor_EXUWP_0101"
  TraceSamplingRate=0
Private
  Chip="Smc_ExpBoardSMC_0101"
  FailureDebounceCount=10
  Mask=255
  Offset=134239488
  Size=1
  SuccessDebounceCount=10
  Type=0

~ ~ # 
~ ~ # 
~ ~ # mdbctl setprop modify Accessor_EXUWP_0101 bmc.kepler.Accessor Value 0 
Success

~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Read a{ss}uyu 0 134239488 1 255
ay 1 1
~ ~ # mdbctl setprop modify Accessor_EXUWP_0101 bmc.kepler.Accessor Value 1
Success

~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Read a{ss}uyu 0 134239488 1 255
ay 1 1
~ ~ # mdbctl setprop set Accessor_EXUWP_0101 bmc.kepler.Accessor Value 0 
Success

~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Read a{ss}uyu 0 134239488 1 255
ay 1 1
~ ~ # mdbctl setprop set Accessor_EXUWP_0101 bmc.kepler.Accessor Value 1
Success

~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Read a{ss}uyu 0 134239488 1 255
ay 1 1
~ ~ # mdbctl setprop modify Accessor_EXUWP_0101 bmc.kepler.Accessor Value 0 
Success

~ ~ # mdbctl lsprop Accessor_EXUWP_0101
bmc.kepler.Accessor
  Status=0
  Value=1
bmc.kepler.Object.Properties
  ClassName="Accessor"
  ObjectIdentifier=[1,"1","1","0101"]
  ObjectName="Accessor_EXUWP_0101"
  TraceSamplingRate=0
Private
  Chip="Smc_ExpBoardSMC_0101"
  FailureDebounceCount=10
  Mask=255
  Offset=134239488
  Size=1
  SuccessDebounceCount=10
  Type=0

~ ~ # mdbctl setprop set Accessor_EXUWP_0101 bmc.kepler.Accessor Value 0 
Success

~ ~ # mdbctl lsprop Accessor_EXUWP_0101
bmc.kepler.Accessor
  Status=0
  Value=0
bmc.kepler.Object.Properties
  ClassName="Accessor"
  ObjectIdentifier=[1,"1","1","0101"]
  ObjectName="Accessor_EXUWP_0101"
  TraceSamplingRate=0
Private
  Chip="Smc_ExpBoardSMC_0101"
  FailureDebounceCount=10
  Mask=255
  Offset=134239488
  Size=1
  SuccessDebounceCount=10
  Type=0

~ ~ #

你通过busctl写完后再读呢

busctl读写是正常的
~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Read a{ss}uyu 0 134239488 1 255
ay 1 1
~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Write a{ss}uyuay 0 134239744 1 255 1 0
~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Read a{ss}uyu 0 134239488 1 255
ay 1 0
~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Write a{ss}uyuay 0 134239744 1 255 1 1
~ ~ # busctl --user call bmc.kepler.hwproxy /bmc/kepler/Chip/Smc/Smc_ExpBoardSMC_0101 bmc.kepler.Chip.BitIO Read a{ss}uyu 0 134239488 1 255
ay 1 1
~ ~ #

你是不是之前用过mdbctl setprop set,先unset取消覆写,再用modify试试

我看你写的命令字和Accessor配置的偏移不一样,如果要用134239744写才能关闭写保护的话,Accessor偏移应该配134239744。

使用134239744可以了。
社区仓都用的134239488,所以沿用的,而且134239488也能读到值。
CPLD支持情况
企业微信截图_17757911062822
命令字解析情况

134239744命令字
Func[bit 26-31]: 2
Cmd[bit 10-25] : 15
M/S[bit 9]     : 1
R/W[bit 8]     : 0
134239488命令字
Func[bit 26-31]: 2
Cmd[bit 10-25] : 15
M/S[bit 9]     : 0
R/W[bit 8]     : 1

Accessor对offset的有什么要求吗,写操作的只能配置写的命令字?

你要写数据肯定要用写命令字的,读命令字只能读,写是没有用的,不然也不会分两个命令字。

奇怪开源仓里都用的读命令字