1 /* SPDX-License-Identifier: GPL-2.0-only */
5 * Copyright (C) 2001 Deep Blue Solutions Ltd.
6 * Copyright (C) 2012 ARM Ltd.
9 #include <linux/errno.h>
10 #include <linux/linkage.h>
11 #include <linux/init.h>
12 #include <asm/assembler.h>
13 #include <asm/cpufeature.h>
14 #include <asm/alternative.h>
15 #include <asm/asm-uaccess.h>
18 * caches_clean_inval_pou_macro(start,end) [fixup]
20 * Ensure that the I and D caches are coherent within specified region.
21 * This is typically used when code has been written to a memory region,
22 * and will be executed.
24 * - start - virtual start address of region
25 * - end - virtual end address of region
26 * - fixup - optional label to branch to on user fault
28 .macro caches_clean_inval_pou_macro, fixup
29 alternative_if ARM64_HAS_CACHE_IDC
32 alternative_else_nop_endif
35 dcache_by_line_op cvau, ish, x2, x3, x4, x5, \fixup
37 alternative_if ARM64_HAS_CACHE_DIC
40 alternative_else_nop_endif
41 invalidate_icache_by_line x0, x1, x2, x3, \fixup
46 * caches_clean_inval_pou(start,end)
48 * Ensure that the I and D caches are coherent within specified region.
49 * This is typically used when code has been written to a memory region,
50 * and will be executed.
52 * - start - virtual start address of region
53 * - end - virtual end address of region
55 SYM_FUNC_START(caches_clean_inval_pou)
56 caches_clean_inval_pou_macro
58 SYM_FUNC_END(caches_clean_inval_pou)
59 SYM_FUNC_ALIAS(__pi_caches_clean_inval_pou, caches_clean_inval_pou)
62 * caches_clean_inval_user_pou(start,end)
64 * Ensure that the I and D caches are coherent within specified region.
65 * This is typically used when code has been written to a memory region,
66 * and will be executed.
68 * - start - virtual start address of region
69 * - end - virtual end address of region
71 SYM_FUNC_START(caches_clean_inval_user_pou)
72 uaccess_ttbr0_enable x2, x3, x4
74 caches_clean_inval_pou_macro 2f
77 uaccess_ttbr0_disable x1, x2
82 SYM_FUNC_END(caches_clean_inval_user_pou)
85 * icache_inval_pou(start,end)
87 * Ensure that the I cache is invalid within specified region.
89 * - start - virtual start address of region
90 * - end - virtual end address of region
92 SYM_FUNC_START(icache_inval_pou)
93 alternative_if ARM64_HAS_CACHE_DIC
96 alternative_else_nop_endif
98 invalidate_icache_by_line x0, x1, x2, x3
100 SYM_FUNC_END(icache_inval_pou)
103 * dcache_clean_inval_poc(start, end)
105 * Ensure that any D-cache lines for the interval [start, end)
106 * are cleaned and invalidated to the PoC.
108 * - start - virtual start address of region
109 * - end - virtual end address of region
111 SYM_FUNC_START(__pi_dcache_clean_inval_poc)
112 dcache_by_line_op civac, sy, x0, x1, x2, x3
114 SYM_FUNC_END(__pi_dcache_clean_inval_poc)
115 SYM_FUNC_ALIAS(dcache_clean_inval_poc, __pi_dcache_clean_inval_poc)
118 * dcache_clean_pou(start, end)
120 * Ensure that any D-cache lines for the interval [start, end)
121 * are cleaned to the PoU.
123 * - start - virtual start address of region
124 * - end - virtual end address of region
126 SYM_FUNC_START(dcache_clean_pou)
127 alternative_if ARM64_HAS_CACHE_IDC
130 alternative_else_nop_endif
131 dcache_by_line_op cvau, ish, x0, x1, x2, x3
133 SYM_FUNC_END(dcache_clean_pou)
136 * dcache_inval_poc(start, end)
138 * Ensure that any D-cache lines for the interval [start, end)
139 * are invalidated. Any partial lines at the ends of the interval are
140 * also cleaned to PoC to prevent data loss.
142 * - start - kernel start address of region
143 * - end - kernel end address of region
145 SYM_FUNC_START(__pi_dcache_inval_poc)
146 dcache_line_size x2, x3
148 tst x1, x3 // end cache line aligned?
151 dc civac, x1 // clean & invalidate D / U line
152 1: tst x0, x3 // start cache line aligned?
155 dc civac, x0 // clean & invalidate D / U line
157 2: dc ivac, x0 // invalidate D / U line
163 SYM_FUNC_END(__pi_dcache_inval_poc)
164 SYM_FUNC_ALIAS(dcache_inval_poc, __pi_dcache_inval_poc)
167 * dcache_clean_poc(start, end)
169 * Ensure that any D-cache lines for the interval [start, end)
170 * are cleaned to the PoC.
172 * - start - virtual start address of region
173 * - end - virtual end address of region
175 SYM_FUNC_START(__pi_dcache_clean_poc)
176 dcache_by_line_op cvac, sy, x0, x1, x2, x3
178 SYM_FUNC_END(__pi_dcache_clean_poc)
179 SYM_FUNC_ALIAS(dcache_clean_poc, __pi_dcache_clean_poc)
182 * dcache_clean_pop(start, end)
184 * Ensure that any D-cache lines for the interval [start, end)
185 * are cleaned to the PoP.
187 * - start - virtual start address of region
188 * - end - virtual end address of region
190 SYM_FUNC_START(__pi_dcache_clean_pop)
191 alternative_if_not ARM64_HAS_DCPOP
193 alternative_else_nop_endif
194 dcache_by_line_op cvap, sy, x0, x1, x2, x3
196 SYM_FUNC_END(__pi_dcache_clean_pop)
197 SYM_FUNC_ALIAS(dcache_clean_pop, __pi_dcache_clean_pop)