ppc32: reinstate collection of cache-line-size info from the auxv
array at startup. This is used in m_transtab. However this info is
not yet fed to Vex, so it's still important to zero-out the auxv field
holding cache line size info passed to the client, so as to stop the
client's glibc using dcbz. This will be fixed.
Also get rid of a bunch more ppc32-specific vdso stuff in m_main that
doesn't need to be done. This now means ppc32-linux specifics in
m_main are only marginally intrusive than the x86-linux or amd64-linux
specifics in m_main.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4052 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c
index a0e3b0c..e3be88f 100644
--- a/coregrind/m_machine.c
+++ b/coregrind/m_machine.c
@@ -196,6 +196,16 @@
return VG_INVALID_THREADID;
}
+//////////////////////////////////////////////////////////////////
+// Architecture specifics
+
+// PPC: what is the cache line size (for dcbz etc) ?
+// This info is harvested on Linux at startup from the AT_SYSINFO
+// entries. 0 means not-yet-set.
+#if defined(VGA_ppc32)
+Int VG_(cache_line_size_ppc32) = 0;
+#endif
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 65dbd91..ee6fde2 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -122,12 +122,6 @@
static Int vg_argc;
static Char **vg_argv;
-#if defined(VGP_ppc32_linux)
-/* From the aux vector */
-Int VG_(cache_line_size);
-UInt VG_(hardware_capabilities);
-#endif
-
/*====================================================================*/
/*=== Counters, for profiling purposes only ===*/
@@ -173,28 +167,28 @@
found |= 2;
break;
-#if defined(VGP_ppc32_linux)
+# if defined(VGP_ppc32_linux)
case AT_DCACHEBSIZE:
case AT_ICACHEBSIZE:
case AT_UCACHEBSIZE:
- VG_(debugLog)(1, "main", "PPC32 cache line size %u (type %u)\n",
- (UInt)auxv->u.a_val, (UInt)auxv->a_type );
- if (auxv->u.a_val)
- VG_(cache_line_size) = auxv->u.a_val;
- // XXX: Nasty hack to stop use of badly implemented
- // cache-control instns in vex (dcbz)
- auxv->u.a_val = 0;
+ if (auxv->u.a_val > 0) {
+ VG_(cache_line_size_ppc32) = auxv->u.a_val;
+ VG_(debugLog)(1, "main",
+ "PPC32 cache line size %u (type %u)\n",
+ (UInt)auxv->u.a_val, (UInt)auxv->a_type );
+ }
+ /* HACK: Tell glibc we don't know what the line size is.
+ This stops it using dcbz. */
+ auxv->u.a_val = 0;
break;
-
- case AT_HWCAP:
- VG_(hardware_capabilities) = auxv->u.a_val;
- break;
-#endif
+# endif
case AT_PHDR:
VG_(valgrind_base) = VG_PGROUNDDN(auxv->u.a_val);
break;
+ default:
+ break;
}
if ( found != (1|2) ) {
diff --git a/coregrind/m_transtab.c b/coregrind/m_transtab.c
index 5dcba0c..ec0644a 100644
--- a/coregrind/m_transtab.c
+++ b/coregrind/m_transtab.c
@@ -30,12 +30,13 @@
*/
#include "pub_core_basics.h"
+#include "pub_core_machine.h" // ppc32: VG_(cache_line_size_ppc32)
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
-#include "pub_core_libcmman.h" // For VG_(get_memory_from_mmap)()
+#include "pub_core_libcmman.h" // For VG_(get_memory_from_mmap)()
#include "pub_core_libcprint.h"
#include "pub_core_options.h"
-#include "pub_core_tooliface.h" // For VG_(details).avg_translation_sizeB
+#include "pub_core_tooliface.h" // For VG_(details).avg_translation_sizeB
#include "pub_core_transtab.h"
/* #define DEBUG_TRANSTAB */
@@ -324,13 +325,16 @@
invalidateFastCache();
}
-#if defined(VGA_ppc32)
-static void invalidate_icache(void *ptr, int nbytes)
+static void invalidate_icache ( void *ptr, Int nbytes )
{
- unsigned long startaddr = (unsigned long) ptr;
- unsigned long endaddr = startaddr + nbytes;
- unsigned long addr;
- unsigned long cls = 16; //VG_(cache_line_size);
+# if defined(VGA_ppc32)
+ Addr startaddr = (Addr) ptr;
+ Addr endaddr = startaddr + nbytes;
+ Addr cls = VG_(cache_line_size_ppc32);
+ Addr addr;
+
+ /* Surely no real cache would have a different line size? */
+ vg_assert(cls == 16 || cls == 32 || cls == 64);
startaddr &= ~(cls - 1);
for (addr = startaddr; addr < endaddr; addr += cls)
@@ -339,8 +343,17 @@
for (addr = startaddr; addr < endaddr; addr += cls)
asm volatile("icbi 0,%0" : : "r" (addr));
asm volatile("sync; isync");
+
+# elif defined(VGA_x86)
+ /* no need to do anything, hardware provides coherence */
+
+# elif defined(VGA_amd64)
+ /* no need to do anything, hardware provides coherence */
+
+# else
+# error "Unknown ARCH"
+# endif
}
-#endif
/* Add a translation of vge to TT/TC. The translation is temporarily
@@ -421,9 +434,7 @@
sectors[y].tc_next += reqdQ;
sectors[y].tt_n_inuse++;
-#if defined(VGA_ppc32)
invalidate_icache( dstP, code_len );
-#endif
/* more paranoia */
tce2 = sectors[y].tc_next;
diff --git a/coregrind/pub_core_machine.h b/coregrind/pub_core_machine.h
index 9612f31..660d3ff 100644
--- a/coregrind/pub_core_machine.h
+++ b/coregrind/pub_core_machine.h
@@ -88,6 +88,15 @@
// Offsets for the Vex state
#define VG_O_STACK_PTR (offsetof(VexGuestArchState, VG_STACK_PTR))
+// Architecture specifics
+
+// PPC: what is the cache line size (for dcbz etc) ?
+// This info is harvested on Linux at startup from the AT_SYSINFO
+// entries.
+#if defined(VGA_ppc32)
+extern Int VG_(cache_line_size_ppc32);
+#endif
+
#endif // __PUB_CORE_MACHINE_H
/*--------------------------------------------------------------------*/