linux aarch64 __inval_dcache_area(kaddr, size)
阿新 • • 發佈:2022-03-06
__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 are6 * 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 region18 * - 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; } }