1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright IBM Corp. 2022
4 */
5
6 #include <linux/cpufeature.h>
7 #include <linux/export.h>
8 #include <linux/bug.h>
9 #include <asm/machine.h>
10 #include <asm/elf.h>
11
12 enum {
13 TYPE_HWCAP,
14 TYPE_FACILITY,
15 TYPE_MACHINE,
16 };
17
18 struct s390_cpu_feature {
19 unsigned int type : 4;
20 unsigned int num : 28;
21 };
22
23 static struct s390_cpu_feature s390_cpu_features[MAX_CPU_FEATURES] = {
24 [S390_CPU_FEATURE_MSA] = {.type = TYPE_HWCAP, .num = HWCAP_NR_MSA},
25 [S390_CPU_FEATURE_VXRS] = {.type = TYPE_HWCAP, .num = HWCAP_NR_VXRS},
26 [S390_CPU_FEATURE_UV] = {.type = TYPE_FACILITY, .num = 158},
27 [S390_CPU_FEATURE_D288] = {.type = TYPE_MACHINE, .num = MFEATURE_DIAG288},
28 };
29
30 /*
31 * cpu_have_feature - Test CPU features on module initialization
32 */
cpu_have_feature(unsigned int num)33 int cpu_have_feature(unsigned int num)
34 {
35 struct s390_cpu_feature *feature;
36
37 if (WARN_ON_ONCE(num >= MAX_CPU_FEATURES))
38 return 0;
39 feature = &s390_cpu_features[num];
40 switch (feature->type) {
41 case TYPE_HWCAP:
42 return !!(elf_hwcap & BIT(feature->num));
43 case TYPE_FACILITY:
44 return test_facility(feature->num);
45 case TYPE_MACHINE:
46 return test_machine_feature(feature->num);
47 default:
48 WARN_ON_ONCE(1);
49 return 0;
50 }
51 }
52 EXPORT_SYMBOL(cpu_have_feature);
53