1 /*-
2 * Copyright 2016 Svatopluk Kraus <skra@FreeBSD.org>
3 * Copyright 2016 Michal Meloun <mmel@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: releng/11.0/sys/arm/include/cpu-v4.h 300694 2016-05-25 19:44:26Z ian $
28 */
29 #ifndef MACHINE_CPU_V4_H
30 #define MACHINE_CPU_V4_H
31
32 /* There are no user serviceable parts here, they may change without notice */
33 #ifndef _KERNEL
34 #error Only include this file in the kernel
35 #endif
36
37 #include <machine/atomic.h>
38 #include <machine/cpufunc.h>
39 #include <machine/cpuinfo.h>
40 #include <machine/sysreg.h>
41
42 #if __ARM_ARCH >= 6
43 #error Never include this file for ARMv6
44 #else
45
46 #define CPU_ASID_KERNEL 0
47
48 /*
49 * Macros to generate CP15 (system control processor) read/write functions.
50 */
51 #define _FX(s...) #s
52
53 #define _RF0(fname, aname...) \
54 static __inline register_t \
55 fname(void) \
56 { \
57 register_t reg; \
58 __asm __volatile("mrc\t" _FX(aname): "=r" (reg)); \
59 return(reg); \
60 }
61
62 #define _R64F0(fname, aname) \
63 static __inline uint64_t \
64 fname(void) \
65 { \
66 uint64_t reg; \
67 __asm __volatile("mrrc\t" _FX(aname): "=r" (reg)); \
68 return(reg); \
69 }
70
71 #define _WF0(fname, aname...) \
72 static __inline void \
73 fname(void) \
74 { \
75 __asm __volatile("mcr\t" _FX(aname)); \
76 }
77
78 #define _WF1(fname, aname...) \
79 static __inline void \
80 fname(register_t reg) \
81 { \
82 __asm __volatile("mcr\t" _FX(aname):: "r" (reg)); \
83 }
84
85
86 /*
87 * Publicly accessible functions
88 */
89
90
91 /* Various control registers */
92
93 _RF0(cp15_cpacr_get, CP15_CPACR(%0))
94 _WF1(cp15_cpacr_set, CP15_CPACR(%0))
95 _RF0(cp15_dfsr_get, CP15_DFSR(%0))
96 _RF0(cp15_ttbr_get, CP15_TTBR0(%0))
97 _RF0(cp15_dfar_get, CP15_DFAR(%0))
98 /* XScale */
99 _RF0(cp15_actlr_get, CP15_ACTLR(%0))
100 _WF1(cp15_actlr_set, CP15_ACTLR(%0))
101
102 /*CPU id registers */
103 _RF0(cp15_midr_get, CP15_MIDR(%0))
104 _RF0(cp15_ctr_get, CP15_CTR(%0))
105 _RF0(cp15_tcmtr_get, CP15_TCMTR(%0))
106 _RF0(cp15_tlbtr_get, CP15_TLBTR(%0))
107 _RF0(cp15_sctlr_get, CP15_SCTLR(%0))
108
109 #undef _FX
110 #undef _RF0
111 #undef _WF0
112 #undef _WF1
113
114
115 /*
116 * armv4/5 compatibility shims.
117 *
118 * These functions provide armv4 cache maintenance using the new armv6 names.
119 * Included here are just the functions actually used now in common code; it may
120 * be necessary to add things here over time.
121 *
122 * The callers of the dcache functions expect these routines to handle address
123 * and size values which are not aligned to cacheline boundaries; the armv4 and
124 * armv5 asm code handles that.
125 */
126
127 static __inline void
128 tlb_flush_all(void)
129 {
130 cpu_tlb_flushID();
131 cpu_cpwait();
132 }
133
134 static __inline void
135 icache_sync(vm_offset_t va, vm_size_t size)
136 {
137 cpu_icache_sync_range(va, size);
138 }
139
140 static __inline void
141 dcache_inv_poc(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
142 {
143
144 cpu_dcache_inv_range(va, size);
145 #ifdef ARM_L2_PIPT
146 cpu_l2cache_inv_range(pa, size);
147 #else
148 cpu_l2cache_inv_range(va, size);
149 #endif
150 }
151
152 static __inline void
153 dcache_inv_poc_dma(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
154 {
155
156 /* See armv6 code, above, for why we do L2 before L1 in this case. */
157 #ifdef ARM_L2_PIPT
158 cpu_l2cache_inv_range(pa, size);
159 #else
160 cpu_l2cache_inv_range(va, size);
161 #endif
162 cpu_dcache_inv_range(va, size);
163 }
164
165 static __inline void
166 dcache_wb_poc(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
167 {
168
169 cpu_dcache_wb_range(va, size);
170 #ifdef ARM_L2_PIPT
171 cpu_l2cache_wb_range(pa, size);
172 #else
173 cpu_l2cache_wb_range(va, size);
174 #endif
175 }
176
177 static __inline void
178 dcache_wbinv_poc_all(void)
179 {
180 cpu_idcache_wbinv_all();
181 cpu_l2cache_wbinv_all();
182 }
183
184 #endif /* _KERNEL */
185
186 #endif /* MACHINE_CPU_V4_H */
Cache object: 6038ecdaad55f670973d3aaeaa7d0886
|