You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

禁用DCache导致Cortex-A9上atomic_flag无法设置的问题求助

Cortex-A9禁用DCache后atomic_flag_test_and_set失败问题排查

问题背景

基于Zynq-7000的Cortex-A9处理器,在第二个CPU核上运行裸机代码时,调用DCacheDisable()禁用数据缓存后,atomic_int类型的变量无法通过atomic_flag_test_and_set()设置;不调用禁用缓存的函数时,代码运行完全正常。

触发代码

#define XREG_CONTROL_DCACHE_BIT (0X00000001U << 2U)
#define XREG_CP15_SYS_CONTROL   "p15, 0, %0,  c1,  c0, 0"
#define mfcp(rn)    ({uint32_t rval = 0U; \
             __asm__ __volatile__(\
               "mrc " rn "\n"\
               : "=r" (rval)\
             );\
             rval;\
             })
#define mtcp(rn, v) __asm__ __volatile__(\
             "mcr " rn "\n"\
             : : "r" (v)\
            );

static void DCacheDisable(void) {
    uint32_t CtrlReg;
    /* clean and invalidate the Data cache */
    CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);

    CtrlReg &= ~(XREG_CONTROL_DCACHE_BIT);
    /* disable the Data cache */
    mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);
}

int main(void) {
    DCacheDisable();

    atomic_int flag = 0;
    printf("Before\n");
    atomic_flag_test_and_set(&flag);
    printf("After\n");
}

执行时的汇编循环

dmb     ish
ldrexb  r1, [r3] ; bne jumps here
strexb  r0, r2, [r3]
cmp     r0, #0
bne     -20     ; addr=0x1f011614: main + 0x00000060
dmb     ish

执行时寄存器r0始终为1,说明strexb指令执行失败。

工具链信息

  • Vitis 2022.2
  • arm-xilinx-eabi-gcc.exe (GCC) 11.2.0
  • 编译选项:-O2 -std=c11 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard

排查技术思路

  • 内存属性配置检查:Cortex-A9禁用DCache后,内存访问直接走AXI总线,需确保atomic_int变量所在内存区域配置为**可共享(Shareable)**属性,且内存类型为Device或Normal Non-cacheable Shareable。裸机环境下需检查MMU页表,确保该区域支持独占访问——非共享的非缓存内存无法响应独占监控信号,会导致strexb返回失败。
  • 独占监控器重置:禁用DCache前可能未正确清理独占监控器状态,导致ldrexb无法标记独占区域。可在禁用缓存前添加指令重置本地独占监控器:
    mov r0, #0
    mcr p15, 0, r0, c7, c10, 4 ; DSB
    mcr p15, 0, r0, c7, c10, 5 ; DMB
    mcr p15, 0, r0, c15, c1, 0 ; 重置本地独占监控器
    
  • OpenAMP原子操作适配:检查OpenAMP库中atomic_flag_test_and_set的实现是否适配裸机无Cache场景。部分实现默认依赖Cache开启,需确保指令序列包含正确的内存屏障,且编译器能正确识别原子访问的内存地址。
  • 编译器优化规避:-O2优化可能导致atomic_int变量被优化到寄存器中,可添加volatile修饰(或使用__attribute__((aligned(4)))确保变量4字节对齐——Cortex-A9原子操作要求地址对齐,不对齐会导致strexb失败)。
  • CPU核初始化验证:第二个CPU核启动时需确保内存控制器(如Zynq DDR控制器)配置正确,AXI总线的独占访问功能已启用,避免因内存系统未初始化导致原子操作失败。

内容的提问来源于stack exchange,提问作者hellow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:14:57