/* Scan the Aux Vector for the "Data Cache Block Size" entry. If found
verify that the static extern __cache_line_size is defined by checking
for not NULL. If it is defined then assign the cache block size
- value to __cache_line_size. */
-#define DL_PLATFORM_AUXV \
+ value to __cache_line_size. This is used by memset to
+ optimize setting to zero. We have to detect 8xx processors, which
+ have buggy dcbz implementations that cannot report page faults
+ correctly. That requires reading SPR, which is a privileged
+ operation. Fortunately 2.2.18 and later emulates PowerPC mfspr
+ reads from the PVR register. */
+#ifndef __powerpc64__
+ #define DL_PLATFORM_AUXV \
+ case AT_DCACHEBSIZE: \
+ { \
+ unsigned pvr = 0; \
+ asm ("mfspr %0, 287" : "=r" (pvr)); \
+ if ((pvr & 0xffff0000) == 0x00500000) \
+ break; \
+ } \
+ __cache_line_size = av->a_un.a_val; \
+ break;
+#else
+ #define DL_PLATFORM_AUXV \
case AT_DCACHEBSIZE: \
__cache_line_size = av->a_un.a_val; \
break;
+#endif
#include <sysdeps/unix/sysv/linux/dl-sysdep.c>
/* Initialize the __cache_line_size variable from the aux vector. For the
static case, we also need _dl_hwcap, _dl_hwcap2 and _dl_platform, so we
- can call __tcb_parse_hwcap_and_convert_at_platform (). */
+ can call __tcb_parse_hwcap_and_convert_at_platform ().
+ This is used by memset to optimize setting to zero. We have to
+ detect 8xx processors, which have buggy dcbz implementations that
+ cannot report page faults correctly. That requires reading SPR,
+ which is a privileged operation. Fortunately 2.2.18 and later
+ emulates PowerPC mfspr reads from the PVR register. */
for (ElfW (auxv_t) * av = auxvec; av->a_type != AT_NULL; ++av)
switch (av->a_type)
{
case AT_DCACHEBSIZE:
+#ifndef __powerpc64__
+ {
+ unsigned pvr = 0;
+
+ asm ("mfspr %0, 287" : "=r" (pvr) :);
+ if ((pvr & 0xffff0000) == 0x00500000)
+ break;
+ }
+#endif
__cache_line_size = av->a_un.a_val;
break;
#ifndef SHARED