DC CIVAC 指令详解

ARM架构中的数据缓存清理与无效化操作

这个指令是干啥的?

DC CIVAC 是ARM架构中的一条系统指令,全称是 Data or unified Cache line Clean and Invalidate by VA to PoC

简单来说,它的作用是:

怎么使用这个指令?

DC CIVAC 是一条系统指令,需要在特权模式下执行(通常是EL1或更高权限级别)。

指令编码

op0 op1 CRn CRm op2
0b01 0b011 0b0111 0b1110 0b001

汇编语法

DC CIVAC, <Xt>

其中 <Xt> 是一个64位通用寄存器,包含要操作的虚拟地址。

使用示例

// 假设x0寄存器中包含要操作的虚拟地址
DC CIVAC, x0

注意:在用户模式(EL0)下执行此指令可能会产生权限错误,除非系统明确允许。

什么场景下需要使用?

DC CIVAC 指令在以下场景中非常有用:

1. DMA数据传输

当设备通过DMA直接访问内存时,需要确保缓存中的数据已经写回内存:

// 在DMA读取之前:清理缓存,确保设备获取最新数据
DC CIVAC, x0
// 启动DMA读取操作

2. 自修改代码

当程序修改自身的代码时,需要确保指令缓存与数据缓存的一致性:

// 修改代码段
str x1, [x0]    // 将新指令写入内存
DC CIVAC, x0    // 清理数据缓存
IC IVAU, x0     // 无效化指令缓存
isb             // 确保所有操作完成

3. 多核一致性

在多核系统中,当一个核心修改了共享数据,需要通知其他核心:

// 核心1修改共享数据
str x1, [x0]    // 修改数据
DC CIVAC, x0    // 清理并使缓存行无效
sev             // 发送事件,唤醒其他核心

实际应用示例

Linux内核中的使用

在Linux内核中,DC CIVAC常用于维护缓存一致性:

// arch/arm64/mm/cache.S
ENTRY(__flush_dcache_area)
    // x0: 虚拟地址起始位置
    // x1: 区域大小
    add x1, x0, x1
    sub x1, x1, #1
    bic x0, x0, #(1 << 4) - 1
1:
    dc civac, x0   // 清理并使缓存行无效
    add x0, x0, #(1 << 4)
    cmp x0, x1
    b.lo 1b
    dsb sy
    ret
ENDPROC(__flush_dcache_area)

ATF (ARM Trusted Firmware) 中的使用

在安全启动过程中,ATF使用DC CIVAC确保安全数据的一致性:

// lib/aarch64/cache_helpers.S
func flush_dcache_range
    // x0: 虚拟地址起始位置
    // x1: 虚拟地址结束位置
    mrs x2, ctr_el0
    ubfx x2, x2, #16, #4
    mov x3, #4
    lsl x3, x3, x2
    sub x4, x3, #1
    bic x0, x0, x4
1:
    dc civac, x0   // 清理并使缓存行无效
    add x0, x0, x3
    cmp x0, x1
    b.lo 1b
    dsb sy
    ret
endfunc flush_dcache_range

OP-TEE (开源TEE实现) 中的使用

在安全环境中,OP-TEE使用DC CIVAC保护安全数据:

// core/arch/arm/kernel/cache_helpers_a64.S
LOCAL_FUNC cache_op_inner_dccivac , :
    // x0: 虚拟地址
    // x1: 大小
    add x1, x0, x1
    sub x1, x1, #1
    bic x0, x0, #CACHELINE_MASK
1:
    dc civac, x0   // 清理并使缓存行无效
    add x0, x0, #CACHELINE_SIZE
    cmp x0, x1
    b.lo 1b
    dsb sy
    ret
END_FUNC cache_op_inner_dccivac

权限和异常处理

DC CIVAC指令的执行受到系统权限控制:

提示:在编写系统代码时,需要仔细考虑缓存操作的正确性和性能影响,不必要的缓存操作会显著降低系统性能。