SK-TDA4VM: TDA4VM/J721E:C71x 固件用 CCS 能计算,但用 Linux remoteproc 启动后一直卡在等待共享DDR ready

Part Number: SK-TDA4VM

当前情况是:
1. 同一份 C71x 固件,用 CCS/JTAG 直接加载时,可以正常完成 NUFFT 计算,并且能得到性能结果。
2. 用 Linux remoteproc 从 /lib/firmware/j7-c71_0-fw 启动时,remoteproc 状态是 running,dmesg 里也显示 64800000.dsp is now up。
3. 我已经确认 /lib/firmware/j7-c71_0-fw 就是我编译的固件版本,文件里能 grep 到固件 build tag。
4. Linux 侧通过自定义的 /dev/dsp_shared_mem 映射共享 DDR,能够成功写入数据,并且写入 ready=0xA5A5A5A5 后,Linux 自己读回完全正确。
5. 为了排除 PCIe/XDMA 的影响,我又专门做了一个 manual_feed_dsp 测试程序,完全绕过 PCIe,直接向共享 DDR 写固定测试数据和 ready 标志。Linux 侧读回仍然正确。
6. 但是 DSP 侧阶段标记始终停在 c7000005,对应等待 ready 的循环,没有进入后续计算。
 
共享 DDR 布局如下:
- 0xB8000000: X buffer
- 0xB8040000: Y buffer
- 0xB80A0000: ready flag
- 0xB80FF000: stage marker

1. C7x 固件内存映射与 Linux 保留区域的对应关系

我的设备树使用的是 SDK 自带的 k3-j721e-rtos-memory-map.dtsi,其中为 C71x 保留了:

  • vision_apps_c71_0_dma_memory_region0xB2000000, 1 MB (shared-dma-poolno-map)
  • vision_apps_c71_0_memory_region0xB2100000, 95 MB (shared-dma-poolno-map)
  • vision_apps_shared_region0xB8000000, 512 MB (dma-heap-carveout)

我的 C7x 固件链接器完全按照这些范围分配:

  • DDR_C7x_1_IPC = 0xB2000000 (1 MB) → 对应 c71_0_dma_memory_region
  • DDR_C7x_1_RESOURCE_TABLE = 0xB2100000 → 在 c71_0_memory_region 起始处
  • DDR_C7x_1 (代码/BSS) = 0xB2604000 ~ 0xB8000000 → 在 c71_0_memory_region 范围内
  • SHARED_DDR_PCIE = 0xB8000000 (1 MB, .ddrData 段, type=NOLOAD) → 在 vision_apps_shared_region 范围内

2. 资源表位置

资源表 (ti_ipc_remoteproc_ResourceTable) 使用 __attribute__((section(".resource_table"), aligned(4096))) 放置在 .resource_table 段,链接到 0xB2100000。编译后的 .map 文件确认 .resource_table 在 0xB2100000,大小 0x98 字节。remoteproc 启动日志也显示正常加载:

remoteproc remoteproc2: Booting fw image j7-c71_0-fw
k3-dsp-rproc 64800000.dsp: booting DSP core using boot addr = 0xb2200000
remoteproc2#vdev0buffer: assigned reserved memory node vision-apps-c71-dma-memory@b2000000
 

 Linux 用户态程序使用 /dev/mem + mmap() 写入 0xB8000000 时报错 Operation not permitted/proc/iomem 显示该区域为 reserved

b8000000-d7ffffff : System RAM
b8000000-d7ffffff : reserved

该区域在设备树中是 dma-heap-carveout(没有 no-map),所以 Linux 内核可能不允许通过 /dev/mem 直接映射。请问:

对于 dma-heap-carveout 类型的保留区域,用户态程序通过什么方式访问是正确的?是否需要通过 /dev/dma_heap/ 接口?或者我是否应该为这 1 MB 的 PCIe 共享区域单独添加一个 no-map 的 reserved-memory 节点,使其可以通过 /dev/mem 访问?

 
为什么同一份固件在 CCS/JTAG 下可以正常计算,但在 Linux remoteproc 启动场景下,DSP 看不到 A72 已经写入 shared DDR 的 ready flag?
这是否与 C71x MMU/cache 属性、shared DDR 的 reserved-memory 配置、remoteproc 启动方式,或者 A72/C71x cache coherency 有关?