ARM中的缓存维护指令有哪些,请全部列出来,说明详细的用法,并给出实例和使用场景
ARM架构提供了一系列缓存维护指令,用于管理指令缓存(ICache)和数据缓存(DCache)。以下是完整的ARM缓存维护指令列表和详细说明:
1. 数据缓存维护指令
DC CISW - 按地址清理和无效化数据缓存
DC CISW, <Rt> ; Clean and Invalidate by Set/Way
用法:清理并无效化指定组和路的数据缓存行
场景:精确维护特定缓存行
MOV x0, #(set << 13) | (way << 30) ; 设置组和路信息
DC CISW, x0 ; 清理并无效化该缓存行
DC CIVAC - 按地址清理和无效化到PoC
DC CIVAC, <Rt> ; Clean and Invalidate by VA to PoC
用法:清理并无效化指定虚拟地址对应的数据缓存行到一致性点
场景:DMA传输前后
MOV x0, #BUFFER_ADDRESS
DC CIVAC, x0 ; DMA传输前清理缓存
DSB SY
// 执行DMA操作
DC CIVAC, x0 ; DMA传输后无效化缓存
DSB SY
DC CVAC - 按地址清理到PoC
DC CVAC, <Rt> ; Clean by VA to PoC
用法:清理指定虚拟地址的数据缓存行到内存
场景:将修改的数据写回内存
STR x1, [x0] ; 写入数据
DC CVAC, x0 ; 确保数据写入内存
DSB SY
DC IVAC - 按地址无效化到PoC
DC IVAC, <Rt> ; Invalidate by VA to PoC
用法:无效化指定虚拟地址的数据缓存行
场景:内存内容被其他主控修改后
DC IVAC, x0 ; 无效化缓存,强制重新从内存加载
DSB SY
LDR x1, [x0] ; 重新加载最新数据
DC CSW - 清理数据缓存(按组/路)
DC CSW, <Rt> ; Clean by Set/Way
DC ISW - 无效化数据缓存(按组/路)
DC ISW, <Rt> ; Invalidate by Set/Way
DC ZVA - 按地址清零
DC ZVA, <Rt> ; Zero by VA
用法:将指定虚拟地址对应的缓存行清零
场景:快速内存清零
MOV x0, #BUFFER_ADDRESS
DC ZVA, x0 ; 快速清零缓存行
DSB SY
2. 指令缓存维护指令
IC IALLU - 无效化所有指令缓存到PoU
IC IALLU ; Invalidate All I-caches to PoU
用法:无效化所有指令缓存
场景:自修改代码或动态代码生成后
// 生成新代码到内存
STR x1, [x0] ; 写入新指令
DSB SY ; 确保数据写入完成
IC IALLU ; 无效化指令缓存
DSB SY
ISB ; 同步指令流水线
IC IALLUIS - 无效化所有指令缓存(内部共享)
IC IALLUIS ; Invalidate All I-caches Inner Shareable
IC IVAU - 按地址无效化指令缓存
IC IVAU, <Rt> ; Invalidate by VA to PoU
用法:无效化指定虚拟地址的指令缓存
场景:精确维护指令缓存
MOV x0, #CODE_ADDRESS
DSB SY
IC IVAU, x0 ; 无效化特定地址的指令缓存
DSB SY
ISB
3. 统一缓存维护指令
DC CVAU - 按地址清理到PoU
DC CVAU, <Rt> ; Clean by VA to PoU
4. TLB维护指令
TLBI ALLE1 - 无效化所有EL1 TLB条目
TLBI ALLE1 ; Invalidate All TLB EL1
TLBI VAE1 - 按地址无效化EL1 TLB
TLBI VAE1, <Rt> ; Invalidate by VA EL1
TLBI ASIDE1 - 按ASID无效化EL1 TLB
TLBI ASIDE1, <Rt> ; Invalidate by ASID EL1
5. 完整使用实例
DMA缓冲区管理
// DMA传输前的缓存维护
dma_prepare:
MOV x0, #DMA_BUFFER_ADDR
MOV x1, #BUFFER_SIZE
clean_buffer:
DC CIVAC, x0 // 清理并无效化缓存行
ADD x0, x0, #CACHE_LINE_SIZE
SUBS x1, x1, #CACHE_LINE_SIZE
B.GT clean_buffer
DSB SY // 等待所有操作完成
// 现在可以安全启动DMA读取
// DMA完成后的缓存维护
dma_complete:
MOV x0, #DMA_BUFFER_ADDR
MOV x1, #BUFFER_SIZE
invalidate_buffer:
DC IVAC, x0 // 无效化缓存,重新加载DMA数据
ADD x0, x0, #CACHE_LINE_SIZE
SUBS x1, x1, #CACHE_LINE_SIZE
B.GT invalidate_buffer
DSB SY
动态代码生成
generate_code:
// 1. 写入新代码到内存
MOV x0, #CODE_AREA
MOV x1, #NEW_INSTRUCTIONS
STR x1, [x0]
// 2. 确保数据写入完成
DC CVAU, x0 // 清理数据缓存
DSB SY
// 3. 无效化指令缓存
IC IVAU, x0 // 无效化指令缓存
DSB SY
ISB // 清空流水线
// 4. 现在可以执行新代码
BR x0
完整缓存维护序列
// 维护整个数据缓存
maintain_full_dcache:
MRS x0, CLIDR_EL1 // 读取缓存级别ID寄存器
AND x1, x0, #0x07000000 // 提取Loc字段
LSR x1, x1, #23 // 对齐
CBZ x1, finished // 如果没有缓存则退出
MOV x9, #0 // 级别计数器
level_loop:
ADD x10, x9, x9, LSL #1 // x10 = x9 * 3
LSR x11, x0, x10 // 提取该级别的缓存类型
AND x11, x11, #0x7
CMP x11, #2
B.LT next_level // 如果没有缓存或只有指令缓存
MRS x12, CSSELR_EL1 // 选择当前缓存级别
BFI x12, x9, #1, #3 // 设置级别字段
MSR CSSELR_EL1, x12
ISB
MRS x13, CCSIDR_EL1 // 读取缓存大小ID寄存器
AND x2, x13, #0x7 // 提取行大小
LSR x4, x13, #3
AND x4, x4, #0x3FF // 提取组数
LSR x5, x13, #13
AND x5, x5, #0x7FFF // 提取路数
way_loop:
MOV x6, x5 // 路计数器
set_loop:
MOV x7, x4 // 组计数器
ORR x14, x9, x6, LSL #30 // 构建组/路信息
ORR x14, x14, x7, LSL #13
DC CISW, x14 // 清理并无效化缓存行
SUBS x7, x7, #1 // 下一组
B.GE set_loop
SUBS x6, x6, #1 // 下一路
B.GE way_loop
next_level:
ADD x9, x9, #1 // 下一级别
CMP x9, x1
B.LT level_loop
finished:
DSB SY
6. 重要注意事项
-
内存屏障使用:
DSB SY- 确保所有缓存操作完成ISB- 清空指令流水线
-
缓存一致性点:
- PoC (Point of Coherency) - 系统一致性点
- PoU (Point of Unification) - 指令数据统一点
-
共享域:
- Inner Shareable - 内部可共享域
- Outer Shareable - 外部可共享域
这些指令在操作系统开发、驱动程序、DMA操作和动态代码生成等场景中至关重要。
浙公网安备 33010602011771号