1 /* Check __ppc_get_hwcap() and __ppc_get_at_plaftorm() functionality.
2 Copyright (C) 2015-2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* Tests if the hwcap, hwcap2 and platform data are stored in the TCB. */
26 #include <support/check.h>
27 #include <support/xthread.h>
31 #include <dl-procinfo.h>
33 #ifndef STATIC_TST_HWCAP
35 #include <dl-procinfo.c>
38 /* Offsets copied from tcb-offsets.h. */
41 # define __TPREG "r13"
42 # define __HWCAPOFF -28776
43 # define __ATPLATOFF -28764
46 # define __HWCAPOFF -28736
47 # define __HWCAP2OFF -28732
48 # define __ATPLATOFF -28724
51 uint64_t check_tcbhwcap (long tid
)
54 uint32_t tcb_at_platform
, at_platform
;
55 uint64_t hwcap
, hwcap2
, tcb_hwcap
;
56 const char *at_platform_string
;
58 /* Testing if the hwcap/hwcap2 data is correctly initialized by
61 register unsigned long __tp
__asm__ (__TPREG
);
64 __asm__ ("ld %0,%1(%2)\n"
66 : "i" (__HWCAPOFF
), "b" (__tp
));
70 __asm__ ("lwz %0,%1(%2)\n"
72 : "i" (__HWCAPOFF
), "b" (__tp
));
73 __asm__ ("lwz %0,%1(%2)\n"
75 : "i" (__HWCAP2OFF
), "b" (__tp
));
76 tcb_hwcap
= (h1
>> 32) << 32 | (h2
>> 32);
79 hwcap
= getauxval (AT_HWCAP
);
80 hwcap2
= getauxval (AT_HWCAP2
);
82 /* hwcap contains only the latest supported ISA, the code checks which is
83 and fills the previous supported ones. This is necessary because the
84 same is done in hwcapinfo.c when setting the values that are copied to
87 if (hwcap2
& PPC_FEATURE2_ARCH_2_07
)
88 hwcap
|= PPC_FEATURE_ARCH_2_06
89 | PPC_FEATURE_ARCH_2_05
90 | PPC_FEATURE_POWER5_PLUS
93 else if (hwcap
& PPC_FEATURE_ARCH_2_06
)
94 hwcap
|= PPC_FEATURE_ARCH_2_05
95 | PPC_FEATURE_POWER5_PLUS
98 else if (hwcap
& PPC_FEATURE_ARCH_2_05
)
99 hwcap
|= PPC_FEATURE_POWER5_PLUS
101 | PPC_FEATURE_POWER4
;
102 else if (hwcap
& PPC_FEATURE_POWER5_PLUS
)
103 hwcap
|= PPC_FEATURE_POWER5
104 | PPC_FEATURE_POWER4
;
105 else if (hwcap
& PPC_FEATURE_POWER5
)
106 hwcap
|= PPC_FEATURE_POWER4
;
108 hwcap
= (hwcap
<< 32) + hwcap2
;
110 if ( tcb_hwcap
!= hwcap
)
112 printf ("FAIL: __ppc_get_hwcap() - HWCAP is %" PRIx64
". Should be %"
113 PRIx64
" for thread %ld.\n", tcb_hwcap
, hwcap
, tid
);
117 /* Same test for the platform number. */
118 __asm__ ("lwz %0,%1(%2)\n"
119 : "=r" (tcb_at_platform
)
120 : "i" (__ATPLATOFF
), "b" (__tp
));
122 at_platform_string
= (const char *) getauxval (AT_PLATFORM
);
123 at_platform
= _dl_string_platform (at_platform_string
);
125 if ( tcb_at_platform
!= at_platform
)
127 printf ("FAIL: __ppc_get_at_platform() - AT_PLATFORM is %x. Should be %x"
128 " for thread %ld\n", tcb_at_platform
, at_platform
, tid
);
137 if (check_tcbhwcap ((long) tid
))
150 pthread_t threads
[2];
152 pthread_attr_init (&attr
);
153 pthread_attr_setdetachstate (&attr
, PTHREAD_CREATE_JOINABLE
);
157 /* Check for main. */
158 if (check_tcbhwcap (i
))
163 /* Check for other thread. */
165 threads
[i
] = xpthread_create (&attr
, t1
, (void *)i
);
167 pthread_attr_destroy (&attr
);
168 TEST_VERIFY_EXIT (xpthread_join (threads
[i
]) == NULL
);
170 printf("PASS: HWCAP, HWCAP2 and AT_PLATFORM are correctly set in the TCB for"
177 #include <support/test-driver.c>