JH7110 GMAC0 在自定义 SPL/XV6 中无法访问,求正确初始化序列

标题: JH7110 GMAC0 在自定义 SPL/XV6 中无法访问,求正确初始化序列

硬件环境

  • 开发板:StarFive VisionFive V2 (v1.3B)
  • SoC:JH7110
  • PHY:Motorcomm YT8531 (RGMII 模式)
  • 启动流程:SPL → XV6 (XV6 替代 visionfive2_fw_payload.img,加载到 0x40200000 运行,跳过 OpenSBI 和 U-Boot)

问题描述
我们需要在自定义的 SPL/XV6 环境中初始化 GMAC0 网卡,但始终无法访问 GMAC 寄存器(GMAC_VERSION 读回 0,所有写操作无效)。奇怪的是,在完整的 U-Boot 中,网络工作正常(可以 ping 通),但通过命令行读取 GMAC 寄存器(md 0x1603001c)却返回 0。

已尝试的初始化步骤
我们尝试了以下初始化序列(均在 XV6 的 S 模式或 M 模式汇编中实现),但 GMAC0 寄存器始终不可访问:

  1. IOMUX 配置:设置 AON_IOMUX 中 GMAC0_MDC (offset 0x58) 和 GMAC0_MDIO (offset 0x5c) 的值为 0(选择 GMAC 功能)。写入后读回为 0x00000002(U-Boot 中也如此),表明写操作可能被硬件忽略。

  2. 时钟使能:

    • SYSCRG[0x2C0] (GTXCLK) 置 bit31
    • SYSCRG[0x2D0] (AHB 时钟) 置 bit31
    • SYSCRG[0x2D4] (AXI 时钟) 置 bit31
    • AONCRG[0x08] (GMAC0_TX_CLK) 置 bit31
    • AONCRG[0x0C] (GMAC0_RMII_RTX) 置 bit31
      写入后读回,bit31 均为 0(写操作无效)。
  3. 复位释放:

    • AONCRG[0x38] 清 bit0 (GMAC0 复位),初始值 0x000000e3,清除 bit0 后为 0x000000e2(写入似乎有效)。
    • rstgen 中复位 ID 160 (AXI) 和 161 (AHB) 的对应位置 1,rstgen[5] 初始值为 0,写入 0x03 后读回仍为 0。
  4. 地址窗口配置:STG_SYSCON 的 0x20~0x28 窗口配置写入后读回为 0。

  5. MDC/MDIO 时钟配置:EQOS_MDIO_ADDR 寄存器写入分频值后读回为 0。

  6. 直接寄存器测试:尝试直接写 GMAC0_BASE + 0x14 (MAC 地址低寄存器) 并读回,始终为 0。

所有写操作均未生效,导致 GMAC_VERSION 始终为 0。

我们的疑问

  1. JH7110 的 GMAC0 电源域是否需要通过 PMU 单独开启?我们尝试了 PMU_BASE (0x17030000) 的 SW_TURN_ON_POWER 寄存器,但不知道正确的 power domain mask(猜测是 bit5,但无效)。U-Boot 设备树中未发现 power-domains 属性。

  2. GMAC0 的 AHB/AXI 总线访问是否需要额外的窗口或权限配置?STG_SYSCON 中 0x20~0x28 区域似乎不可写,是否需要在复位后的极早期配置?

  3. U-Boot 是如何使能 GMAC0 的?既然 U-Boot 网络工作,它必然做了正确的初始化。能否提供 U-Boot 中 eth0 初始化的完整寄存器序列(地址和值)?或者指出我们遗漏的关键步骤。

附录:寄存器快照(在 U-Boot ping 成功后读取)

  • GMAC0 registers (all zero)
  • SYSCRG: 0x130202c0=0x00000004, 0x130202c4=0x40000000, 0x130202c8=0x00000040, 0x130202d0=0x40000000, 0x130202d4=0x00000000, 0x130202d8=0x00000008, 0x130202dc=0x00000000
  • AONCRG: 0x17000008=0x80000000, 0x1700000c=0x80000000, 0x17000038=0x000000e2
  • AON_IOMUX: 0x17020058=0x00000002, 0x1702005c=0x00000002
  • STG_SYSCON: 0x10240004=0x00fa2fff, others zero
  • RSTGEN: mostly zero

感谢各位工程师的指导!

u-boot会在没有send/recv的时候执行eth_halt,这时会执行eqos_stop → eqos->config->ops->eqos_stop_resets,gmac又回到了disable状态。所以这时访问gmac是无效的。最简单的方法可以尝试重新编译u-boot并启用CONFIG_NETCONSOLE,然后根据Network console — Das U-Boot unknown version documentation 配置netconsole。我理解没错的话,在netconsole的event loop中,u-boot会在没有net活动的时候执行eth_halt_state_only,这时不会真正stop,即可以看到gmac的所有寄存器状态

使用像 https://pastee.dev/ 这样的网站,这样你粘贴的源代码就不会被论坛标签弄乱。或者提供一个 Git 仓库的链接。