|
|
@@ -126,6 +126,7 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
|
|
|
static void __init setup_processor(void)
|
|
|
{
|
|
|
struct cpu_info *cpu_info;
|
|
|
+ u64 features, block;
|
|
|
|
|
|
cpu_info = lookup_processor_type(read_cpuid_id());
|
|
|
if (!cpu_info) {
|
|
|
@@ -141,6 +142,37 @@ static void __init setup_processor(void)
|
|
|
|
|
|
sprintf(init_utsname()->machine, ELF_PLATFORM);
|
|
|
elf_hwcap = 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * ID_AA64ISAR0_EL1 contains 4-bit wide signed feature blocks.
|
|
|
+ * The blocks we test below represent incremental functionality
|
|
|
+ * for non-negative values. Negative values are reserved.
|
|
|
+ */
|
|
|
+ features = read_cpuid(ID_AA64ISAR0_EL1);
|
|
|
+ block = (features >> 4) & 0xf;
|
|
|
+ if (!(block & 0x8)) {
|
|
|
+ switch (block) {
|
|
|
+ default:
|
|
|
+ case 2:
|
|
|
+ elf_hwcap |= HWCAP_PMULL;
|
|
|
+ case 1:
|
|
|
+ elf_hwcap |= HWCAP_AES;
|
|
|
+ case 0:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ block = (features >> 8) & 0xf;
|
|
|
+ if (block && !(block & 0x8))
|
|
|
+ elf_hwcap |= HWCAP_SHA1;
|
|
|
+
|
|
|
+ block = (features >> 12) & 0xf;
|
|
|
+ if (block && !(block & 0x8))
|
|
|
+ elf_hwcap |= HWCAP_SHA2;
|
|
|
+
|
|
|
+ block = (features >> 16) & 0xf;
|
|
|
+ if (block && !(block & 0x8))
|
|
|
+ elf_hwcap |= HWCAP_CRC32;
|
|
|
}
|
|
|
|
|
|
static void __init setup_machine_fdt(phys_addr_t dt_phys)
|
|
|
@@ -280,6 +312,11 @@ static const char *hwcap_str[] = {
|
|
|
"fp",
|
|
|
"asimd",
|
|
|
"evtstrm",
|
|
|
+ "aes",
|
|
|
+ "pmull",
|
|
|
+ "sha1",
|
|
|
+ "sha2",
|
|
|
+ "crc32",
|
|
|
NULL
|
|
|
};
|
|
|
|