sparc64: Add detection for features new in SPARC-T4.
Compare and branch, pause, and the various new cryptographic opcodes. We advertise the crypto opcodes to userspace using one hwcap bit, HWCAP_SPARC_CRYPTO. This essentially indicates that the %cfr register can be interrograted and used to determine exactly which crypto opcodes are available on the current cpu. We use the %cfr register to report all of the crypto opcodes available in the bootup CPU caps log message, and via /proc/cpuinfo. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -340,7 +340,12 @@ static const char *hwcaps[] = {
|
||||
*/
|
||||
"mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2",
|
||||
"ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau",
|
||||
"ima", "cspare",
|
||||
"ima", "cspare", "pause", "cbcond",
|
||||
};
|
||||
|
||||
static const char *crypto_hwcaps[] = {
|
||||
"aes", "des", "kasumi", "camellia", "md5", "sha1", "sha256",
|
||||
"sha512", "mpmul", "montmul", "montsqr", "crc32c",
|
||||
};
|
||||
|
||||
void cpucap_info(struct seq_file *m)
|
||||
@@ -357,27 +362,61 @@ void cpucap_info(struct seq_file *m)
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
if (caps & HWCAP_SPARC_CRYPTO) {
|
||||
unsigned long cfr;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
for (i = 0; i < ARRAY_SIZE(crypto_hwcaps); i++) {
|
||||
unsigned long bit = 1UL << i;
|
||||
if (cfr & bit) {
|
||||
seq_printf(m, "%s%s",
|
||||
printed ? "," : "", crypto_hwcaps[i]);
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
|
||||
static void __init report_one_hwcap(int *printed, const char *name)
|
||||
{
|
||||
if ((*printed) == 0)
|
||||
printk(KERN_INFO "CPU CAPS: [");
|
||||
printk(KERN_CONT "%s%s",
|
||||
(*printed) ? "," : "", name);
|
||||
if (++(*printed) == 8) {
|
||||
printk(KERN_CONT "]\n");
|
||||
*printed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init report_crypto_hwcaps(int *printed)
|
||||
{
|
||||
unsigned long cfr;
|
||||
int i;
|
||||
|
||||
__asm__ __volatile__("rd %%asr26, %0" : "=r" (cfr));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(crypto_hwcaps); i++) {
|
||||
unsigned long bit = 1UL << i;
|
||||
if (cfr & bit)
|
||||
report_one_hwcap(printed, crypto_hwcaps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void __init report_hwcaps(unsigned long caps)
|
||||
{
|
||||
int i, printed = 0;
|
||||
|
||||
printk(KERN_INFO "CPU CAPS: [");
|
||||
for (i = 0; i < ARRAY_SIZE(hwcaps); i++) {
|
||||
unsigned long bit = 1UL << i;
|
||||
if (caps & bit) {
|
||||
printk(KERN_CONT "%s%s",
|
||||
printed ? "," : "", hwcaps[i]);
|
||||
if (++printed == 8) {
|
||||
printk(KERN_CONT "]\n");
|
||||
printk(KERN_INFO "CPU CAPS: [");
|
||||
printed = 0;
|
||||
}
|
||||
}
|
||||
if (caps & bit)
|
||||
report_one_hwcap(&printed, hwcaps[i]);
|
||||
}
|
||||
printk(KERN_CONT "]\n");
|
||||
if (caps & HWCAP_SPARC_CRYPTO)
|
||||
report_crypto_hwcaps(&printed);
|
||||
if (printed != 0)
|
||||
printk(KERN_CONT "]\n");
|
||||
}
|
||||
|
||||
static unsigned long __init mdesc_cpu_hwcap_list(void)
|
||||
@@ -411,6 +450,10 @@ static unsigned long __init mdesc_cpu_hwcap_list(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(crypto_hwcaps); i++) {
|
||||
if (!strcmp(prop, crypto_hwcaps[i]))
|
||||
caps |= HWCAP_SPARC_CRYPTO;
|
||||
}
|
||||
|
||||
plen = strlen(prop) + 1;
|
||||
prop += plen;
|
||||
|
Reference in New Issue
Block a user