系统相关
首页 > 系统相关> > linux aarch64 __inval_dcache_area(kaddr, size)

linux aarch64 __inval_dcache_area(kaddr, size)

作者:互联网

__inval_dcache_area(kaddr, size)

 

让一段 kaddr 开始的,长度为 size 的 内存 数据 缓存失效

 

在 arch/arm64/mm/cache.S 中实现的这个函数。

 

 1 /*
 2  *    __inval_dcache_area(kaddr, size)
 3  *
 4  *     Ensure that any D-cache lines for the interval [kaddr, kaddr+size)
 5  *     are invalidated. Any partial lines at the ends of the interval are
 6  *    also cleaned to PoC to prevent data loss.
 7  *
 8  *    - kaddr   - kernel address
 9  *    - size    - size in question
10  */
11 SYM_FUNC_START_LOCAL(__dma_inv_area)
12 SYM_FUNC_START_PI(__inval_dcache_area)
13     /* FALLTHROUGH */
14 
15 /*
16  *    __dma_inv_area(start, size)
17  *    - start   - virtual start address of region
18  *    - size    - size in question
19  */
20     add    x1, x1, x0
21     dcache_line_size x2, x3
22     sub    x3, x2, #1
23     tst    x1, x3                // end cache line aligned?
24     bic    x1, x1, x3
25     b.eq    1f
26     dc    civac, x1            // clean & invalidate D / U line
27 1:    tst    x0, x3                // start cache line aligned?
28     bic    x0, x0, x3
29     b.eq    2f
30     dc    civac, x0            // clean & invalidate D / U line
31     b    3f
32 2:    dc    ivac, x0            // invalidate D / U line
33 3:    add    x0, x0, x2
34     cmp    x0, x1
35     b.lo    2b
36     dsb    sy
37     ret
38 SYM_FUNC_END_PI(__inval_dcache_area)
39 SYM_FUNC_END(__dma_inv_area)

 

1、 dcache_line_size 是获取 data cache line size。 参考 https://www.cnblogs.com/zhangzhiwei122/p/15970511.html

2、dc civac <Xn> 是 让 Xn 指向 地址 的  缓存 无效。

 

使用下面的伪代码 表示 操作过程。

void __inval_dcache_area(kaddr, size)
{
   x1_end_addr = kaddr + size;
   x2_cache_line_size = dcache_line_size();
   
   // 处理末尾地址
   if(x1_end_addr & ( x2_cache_line_size - 1 )){
       dc_civac( x1_end_addr)
   }
   
   // 向下对齐
   x1_end_addr = x1_end_addr & ~( x2_cache_line_size - 1 ) //  bic bit clean x1_end_addr.
   
   // 处理起始地址
   if(x0_kaddr  & ( x2_cache_line_size - 1 ) ){
       dc_civac( x0_kaddr )
   }
   // 向下对齐
   x0_kaddr = x0_kaddr & ~( x2_cache_line_size - 1 ) //  bic bit clean x0_kaddr.
   
   // 下一个 cache line size 整数倍 的地址
   x0_kaddr += x2_cache_line_size;
   
   while ( x0_kaddr < x1_end_addr){
       dc_civac( x0_kaddr );
       x0_kaddr += x2_cache_line_size;
   }

}

 

标签:__,inval,aarch64,cache,kaddr,x0,x1,line,size
来源: https://www.cnblogs.com/zhangzhiwei122/p/15971010.html