summaryrefslogtreecommitdiffstats
path: root/sys/arm/include
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2015-05-23 23:05:31 +0000
committerian <ian@FreeBSD.org>2015-05-23 23:05:31 +0000
commit98dff7fa06c2bdb3c4154926f5f55ac43f998467 (patch)
treecd1863aa60b36c2a5a053d59dc6c4ee8f3287f2d /sys/arm/include
parent68a3dfa74060bcbbac11eaa545bab9c26c9f879e (diff)
downloadFreeBSD-src-98dff7fa06c2bdb3c4154926f5f55ac43f998467.zip
FreeBSD-src-98dff7fa06c2bdb3c4154926f5f55ac43f998467.tar.gz
MFC r279810, r279811:
Clean data cache before instruction cache in armv7_icache_sync_range(). Add minimum cache line sizes to struct cpuinfo, use them in the new cache maintenance routines. Also add a routine to invalidate the branch cache.
Diffstat (limited to 'sys/arm/include')
-rw-r--r--sys/arm/include/cpu-v6.h30
-rw-r--r--sys/arm/include/cpuinfo.h6
2 files changed, 29 insertions, 7 deletions
diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h
index 8d1a413..55c4434 100644
--- a/sys/arm/include/cpu-v6.h
+++ b/sys/arm/include/cpu-v6.h
@@ -37,6 +37,9 @@
#define CPU_ASID_KERNEL 0
+vm_offset_t dcache_wb_pou_checked(vm_offset_t, vm_size_t);
+vm_offset_t icache_inv_pou_checked(vm_offset_t, vm_size_t);
+
/*
* Macros to generate CP15 (system control processor) read/write functions.
*/
@@ -295,7 +298,7 @@ icache_sync(vm_offset_t sva, vm_size_t size)
vm_offset_t eva = sva + size;
dsb();
- for (va = sva; va < eva; va += arm_dcache_align) {
+ for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
#if __ARM_ARCH >= 7 && defined SMP
_CP15_DCCMVAU(va);
#else
@@ -325,6 +328,19 @@ icache_inv_all(void)
isb();
}
+/* Invalidate branch predictor buffer */
+static __inline void
+bpb_inv_all(void)
+{
+#if __ARM_ARCH >= 7 && defined SMP
+ _CP15_BPIALLIS();
+#else
+ _CP15_BPIALL();
+#endif
+ dsb();
+ isb();
+}
+
/* Write back D-cache to PoU */
static __inline void
dcache_wb_pou(vm_offset_t sva, vm_size_t size)
@@ -333,7 +349,7 @@ dcache_wb_pou(vm_offset_t sva, vm_size_t size)
vm_offset_t eva = sva + size;
dsb();
- for (va = sva; va < eva; va += arm_dcache_align) {
+ for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
#if __ARM_ARCH >= 7 && defined SMP
_CP15_DCCMVAU(va);
#else
@@ -351,7 +367,7 @@ dcache_inv_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size)
vm_offset_t eva = sva + size;
/* invalidate L1 first */
- for (va = sva; va < eva; va += arm_dcache_align) {
+ for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
_CP15_DCIMVAC(va);
}
dsb();
@@ -361,7 +377,7 @@ dcache_inv_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size)
dsb();
/* then L1 again */
- for (va = sva; va < eva; va += arm_dcache_align) {
+ for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
_CP15_DCIMVAC(va);
}
dsb();
@@ -376,7 +392,7 @@ dcache_wb_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size)
dsb();
- for (va = sva; va < eva; va += arm_dcache_align) {
+ for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
_CP15_DCCMVAC(va);
}
dsb();
@@ -394,7 +410,7 @@ dcache_wbinv_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size)
dsb();
/* write back L1 first */
- for (va = sva; va < eva; va += arm_dcache_align) {
+ for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
_CP15_DCCMVAC(va);
}
dsb();
@@ -403,7 +419,7 @@ dcache_wbinv_poc(vm_offset_t sva, vm_paddr_t pa, vm_size_t size)
cpu_l2cache_wbinv_range(pa, size);
/* then invalidate L1 */
- for (va = sva; va < eva; va += arm_dcache_align) {
+ for (va = sva; va < eva; va += cpuinfo.dcache_line_size) {
_CP15_DCIMVAC(va);
}
dsb();
diff --git a/sys/arm/include/cpuinfo.h b/sys/arm/include/cpuinfo.h
index f347294..ce0d8e6 100644
--- a/sys/arm/include/cpuinfo.h
+++ b/sys/arm/include/cpuinfo.h
@@ -82,6 +82,12 @@ struct cpuinfo {
int generic_timer_ext;
int virtualization_ext;
int security_ext;
+
+ /* L1 cache info */
+ int dcache_line_size;
+ int dcache_line_mask;
+ int icache_line_size;
+ int icache_line_mask;
};
extern struct cpuinfo cpuinfo;
OpenPOWER on IntegriCloud