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 ---*/
/*--------------------------------------------------------------------*/
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 ===*/
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;
- break;
-
- case AT_HWCAP:
- VG_(hardware_capabilities) = auxv->u.a_val;
+ 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;
-#endif
+# endif
case AT_PHDR:
VG_(valgrind_base) = VG_PGROUNDDN(auxv->u.a_val);
break;
+ default:
+ break;
}
if ( found != (1|2) ) {
*/
#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 */
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)
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
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;
// 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
/*--------------------------------------------------------------------*/