diff options
-rw-r--r-- | arch/arm64/include/uapi/asm/hwcap.h | 6 | ||||
-rw-r--r-- | arch/arm64/kernel/setup.c | 37 |
2 files changed, 42 insertions, 1 deletions
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h index 9b12476e9c85..73cf0f54d57c 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h | |||
@@ -22,6 +22,10 @@ | |||
22 | #define HWCAP_FP (1 << 0) | 22 | #define HWCAP_FP (1 << 0) |
23 | #define HWCAP_ASIMD (1 << 1) | 23 | #define HWCAP_ASIMD (1 << 1) |
24 | #define HWCAP_EVTSTRM (1 << 2) | 24 | #define HWCAP_EVTSTRM (1 << 2) |
25 | 25 | #define HWCAP_AES (1 << 3) | |
26 | #define HWCAP_PMULL (1 << 4) | ||
27 | #define HWCAP_SHA1 (1 << 5) | ||
28 | #define HWCAP_SHA2 (1 << 6) | ||
29 | #define HWCAP_CRC32 (1 << 7) | ||
26 | 30 | ||
27 | #endif /* _UAPI__ASM_HWCAP_H */ | 31 | #endif /* _UAPI__ASM_HWCAP_H */ |
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 82d65bb536b2..bb33fff09ba2 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c | |||
@@ -126,6 +126,7 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id) | |||
126 | static void __init setup_processor(void) | 126 | static void __init setup_processor(void) |
127 | { | 127 | { |
128 | struct cpu_info *cpu_info; | 128 | struct cpu_info *cpu_info; |
129 | u64 features, block; | ||
129 | 130 | ||
130 | cpu_info = lookup_processor_type(read_cpuid_id()); | 131 | cpu_info = lookup_processor_type(read_cpuid_id()); |
131 | if (!cpu_info) { | 132 | if (!cpu_info) { |
@@ -141,6 +142,37 @@ static void __init setup_processor(void) | |||
141 | 142 | ||
142 | sprintf(init_utsname()->machine, ELF_PLATFORM); | 143 | sprintf(init_utsname()->machine, ELF_PLATFORM); |
143 | elf_hwcap = 0; | 144 | elf_hwcap = 0; |
145 | |||
146 | /* | ||
147 | * ID_AA64ISAR0_EL1 contains 4-bit wide signed feature blocks. | ||
148 | * The blocks we test below represent incremental functionality | ||
149 | * for non-negative values. Negative values are reserved. | ||
150 | */ | ||
151 | features = read_cpuid(ID_AA64ISAR0_EL1); | ||
152 | block = (features >> 4) & 0xf; | ||
153 | if (!(block & 0x8)) { | ||
154 | switch (block) { | ||
155 | default: | ||
156 | case 2: | ||
157 | elf_hwcap |= HWCAP_PMULL; | ||
158 | case 1: | ||
159 | elf_hwcap |= HWCAP_AES; | ||
160 | case 0: | ||
161 | break; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | block = (features >> 8) & 0xf; | ||
166 | if (block && !(block & 0x8)) | ||
167 | elf_hwcap |= HWCAP_SHA1; | ||
168 | |||
169 | block = (features >> 12) & 0xf; | ||
170 | if (block && !(block & 0x8)) | ||
171 | elf_hwcap |= HWCAP_SHA2; | ||
172 | |||
173 | block = (features >> 16) & 0xf; | ||
174 | if (block && !(block & 0x8)) | ||
175 | elf_hwcap |= HWCAP_CRC32; | ||
144 | } | 176 | } |
145 | 177 | ||
146 | static void __init setup_machine_fdt(phys_addr_t dt_phys) | 178 | static void __init setup_machine_fdt(phys_addr_t dt_phys) |
@@ -280,6 +312,11 @@ static const char *hwcap_str[] = { | |||
280 | "fp", | 312 | "fp", |
281 | "asimd", | 313 | "asimd", |
282 | "evtstrm", | 314 | "evtstrm", |
315 | "aes", | ||
316 | "pmull", | ||
317 | "sha1", | ||
318 | "sha2", | ||
319 | "crc32", | ||
283 | NULL | 320 | NULL |
284 | }; | 321 | }; |
285 | 322 | ||