svn commit: r266373 - in stable/10/sys/arm: arm include
Ian Lepore
ian at FreeBSD.org
Sat May 17 22:50:18 UTC 2014
Author: ian
Date: Sat May 17 22:50:16 2014
New Revision: 266373
URL: http://svnweb.freebsd.org/changeset/base/266373
Log:
MFC 264990, 264994, 265020, 265025:
Call cpu_icache_sync_range() rather than sync_all since we know the range
and flushing the entire icache is needlessly expensive.
Provide a proper armv7 implementation of icache_sync_all rather than
using armv7_idcache_wbinv_all, because wbinv_all doesn't broadcast the
operation to other cores. In elf_cpu_load_file() use icache_sync_all()
and explain why it's needed (and why other sync operations aren't).
Remove cpu_idcache_wbinv_all() from kdb_cpu_trap(), it's no longer needed.
Explain why wbinv_all is SMP-safe when dumping, and add a missing l2 cache
flush. (Either it was missing here, or it isn't needed in the minidump
case. Adding it here seems like the safer path to consistancy.)
Modified:
stable/10/sys/arm/arm/cpufunc.c
stable/10/sys/arm/arm/cpufunc_asm_armv7.S
stable/10/sys/arm/arm/dump_machdep.c
stable/10/sys/arm/arm/elf_machdep.c
stable/10/sys/arm/include/cpufunc.h
stable/10/sys/arm/include/kdb.h
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/arm/arm/cpufunc.c
==============================================================================
--- stable/10/sys/arm/arm/cpufunc.c Sat May 17 22:31:40 2014 (r266372)
+++ stable/10/sys/arm/arm/cpufunc.c Sat May 17 22:50:16 2014 (r266373)
@@ -769,7 +769,7 @@ struct cpu_functions cortexa_cpufuncs =
/* Cache operations */
- armv7_idcache_wbinv_all, /* icache_sync_all */
+ armv7_icache_sync_all, /* icache_sync_all */
armv7_icache_sync_range, /* icache_sync_range */
armv7_dcache_wbinv_all, /* dcache_wbinv_all */
Modified: stable/10/sys/arm/arm/cpufunc_asm_armv7.S
==============================================================================
--- stable/10/sys/arm/arm/cpufunc_asm_armv7.S Sat May 17 22:31:40 2014 (r266372)
+++ stable/10/sys/arm/arm/cpufunc_asm_armv7.S Sat May 17 22:50:16 2014 (r266373)
@@ -250,6 +250,13 @@ ENTRY(armv7_idcache_wbinv_range)
RET
END(armv7_idcache_wbinv_range)
+ENTRY_NP(armv7_icache_sync_all)
+ mcr p15, 0, r0, c7, c1, 0 /* Invalidate all I cache to PoU Inner Shareable */
+ isb /* instruction synchronization barrier */
+ dsb /* data synchronization barrier */
+ RET
+END(armv7_icache_sync_all)
+
ENTRY_NP(armv7_icache_sync_range)
ldr ip, .Larmv7_line_size
.Larmv7_sync_next:
Modified: stable/10/sys/arm/arm/dump_machdep.c
==============================================================================
--- stable/10/sys/arm/arm/dump_machdep.c Sat May 17 22:31:40 2014 (r266372)
+++ stable/10/sys/arm/arm/dump_machdep.c Sat May 17 22:50:16 2014 (r266373)
@@ -174,8 +174,14 @@ cb_dumpdata(struct md_pa *mdp, int seqnr
printf(" chunk %d: %dMB (%d pages)", seqnr, pgs * PAGE_SIZE / (
1024*1024), pgs);
- /* Make sure we write coherent datas. */
+ /*
+ * Make sure we write coherent data. Note that in the SMP case this
+ * only operates on the L1 cache of the current CPU, but all other CPUs
+ * have already been stopped, and their flush/invalidate was done as
+ * part of stopping.
+ */
cpu_idcache_wbinv_all();
+ cpu_l2cache_wbinv_all();
#ifdef __XSCALE__
xscale_cache_clean_minidata();
#endif
Modified: stable/10/sys/arm/arm/elf_machdep.c
==============================================================================
--- stable/10/sys/arm/arm/elf_machdep.c Sat May 17 22:31:40 2014 (r266372)
+++ stable/10/sys/arm/arm/elf_machdep.c Sat May 17 22:50:16 2014 (r266373)
@@ -220,9 +220,19 @@ int
elf_cpu_load_file(linker_file_t lf __unused)
{
- cpu_idcache_wbinv_all();
- cpu_l2cache_wbinv_all();
- cpu_tlb_flushID();
+ /*
+ * The pmap code does not do an icache sync upon establishing executable
+ * mappings in the kernel pmap. It's an optimization based on the fact
+ * that kernel memory allocations always have EXECUTABLE protection even
+ * when the memory isn't going to hold executable code. The only time
+ * kernel memory holding instructions does need a sync is after loading
+ * a kernel module, and that's when this function gets called. Normal
+ * data cache maintenance has already been done by the IO code, and TLB
+ * maintenance has been done by the pmap code, so all we have to do here
+ * is invalidate the instruction cache (which also invalidates the
+ * branch predictor cache on platforms that have one).
+ */
+ cpu_icache_sync_all();
return (0);
}
Modified: stable/10/sys/arm/include/cpufunc.h
==============================================================================
--- stable/10/sys/arm/include/cpufunc.h Sat May 17 22:31:40 2014 (r266372)
+++ stable/10/sys/arm/include/cpufunc.h Sat May 17 22:50:16 2014 (r266373)
@@ -411,6 +411,7 @@ void armv6_idcache_wbinv_range (vm_offse
void armv7_setttb (u_int);
void armv7_tlb_flushID (void);
void armv7_tlb_flushID_SE (u_int);
+void armv7_icache_sync_all ();
void armv7_icache_sync_range (vm_offset_t, vm_size_t);
void armv7_idcache_wbinv_range (vm_offset_t, vm_size_t);
void armv7_idcache_inv_all (void);
Modified: stable/10/sys/arm/include/kdb.h
==============================================================================
--- stable/10/sys/arm/include/kdb.h Sat May 17 22:31:40 2014 (r266372)
+++ stable/10/sys/arm/include/kdb.h Sat May 17 22:50:16 2014 (r266373)
@@ -49,14 +49,12 @@ static __inline void
kdb_cpu_sync_icache(unsigned char *addr, size_t size)
{
- cpu_icache_sync_all();
+ cpu_icache_sync_range((vm_offset_t)addr, size);
}
static __inline void
kdb_cpu_trap(int type, int code)
{
-
- cpu_idcache_wbinv_all();
}
#endif /* _MACHINE_KDB_H_ */
More information about the svn-src-all
mailing list