Page MenuHomeFreeBSD

D17137.id56656.diff
No OneTemporary

D17137.id56656.diff

Index: sys/arm64/arm64/elf_machdep.c
===================================================================
--- sys/arm64/arm64/elf_machdep.c
+++ sys/arm64/arm64/elf_machdep.c
@@ -55,6 +55,8 @@
#include "linker_if.h"
+u_long elf_hwcap;
+
static struct sysentvec elf64_freebsd_sysvec = {
.sv_size = SYS_MAXSYSCALL,
.sv_table = sysent,
@@ -88,6 +90,7 @@
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
.sv_trap = NULL,
+ .sv_hwcap = &elf_hwcap,
};
INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
Index: sys/arm64/arm64/identcpu.c
===================================================================
--- sys/arm64/arm64/identcpu.c
+++ sys/arm64/arm64/identcpu.c
@@ -44,8 +44,11 @@
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/undefined.h>
+#include <machine/elf.h>
static int ident_lock;
+static void print_cpu_features(u_int cpu);
+static u_long parse_cpu_features_hwcap(u_int cpu);
char machine[] = "arm64";
@@ -408,10 +411,14 @@
}
}
+/* HWCAP */
+extern u_long elf_hwcap;
+
static void
identify_cpu_sysinit(void *dummy __unused)
{
int cpu;
+ u_long hwcap;
/* Create a user visible cpu description with safe values */
memset(&user_cpu_desc, 0, sizeof(user_cpu_desc));
@@ -423,6 +430,11 @@
CPU_FOREACH(cpu) {
print_cpu_features(cpu);
+ hwcap = parse_cpu_features_hwcap(cpu);
+ if (elf_hwcap == 0)
+ elf_hwcap = hwcap;
+ else
+ elf_hwcap &= hwcap;
update_user_regs(cpu);
}
@@ -430,12 +442,101 @@
}
SYSINIT(idenrity_cpu, SI_SUB_SMP, SI_ORDER_ANY, identify_cpu_sysinit, NULL);
-void
+static u_long
+parse_cpu_features_hwcap(u_int cpu)
+{
+ u_long hwcap = 0;
+
+ if (ID_AA64ISAR0_DP(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_DP_IMPL)
+ hwcap |= HWCAP_ASIMDDP;
+
+ if (ID_AA64ISAR0_SM4(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_SM4_IMPL)
+ hwcap |= HWCAP_SM4;
+
+ if (ID_AA64ISAR0_SM3(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_SM3_IMPL)
+ hwcap |= HWCAP_SM3;
+
+ if (ID_AA64ISAR0_RDM(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_RDM_IMPL)
+ hwcap |= HWCAP_ASIMDRDM;
+
+ if (ID_AA64ISAR0_ATOMIC(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_ATOMIC_IMPL)
+ hwcap |= HWCAP_ATOMICS;
+
+ if (ID_AA64ISAR0_CRC32(cpu_desc[cpu].id_aa64isar0) == ID_AA64ISAR0_CRC32_BASE)
+ hwcap |= HWCAP_CRC32;
+
+ switch (ID_AA64ISAR0_SHA2(cpu_desc[cpu].id_aa64isar0)) {
+ case ID_AA64ISAR0_SHA2_BASE:
+ hwcap |= HWCAP_SHA2;
+ break;
+ case ID_AA64ISAR0_SHA2_512:
+ hwcap |= HWCAP_SHA2 | HWCAP_SHA512;
+ break;
+ default:
+ break;
+ }
+
+ if (ID_AA64ISAR0_SHA1(cpu_desc[cpu].id_aa64isar0))
+ hwcap |= HWCAP_SHA1;
+
+ switch (ID_AA64ISAR0_AES(cpu_desc[cpu].id_aa64isar0)) {
+ case ID_AA64ISAR0_AES_BASE:
+ hwcap |= HWCAP_AES;
+ break;
+ case ID_AA64ISAR0_AES_PMULL:
+ hwcap |= HWCAP_PMULL | HWCAP_AES;
+ break;
+ default:
+ break;
+ }
+
+ if (ID_AA64ISAR1_LRCPC(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_LRCPC_IMPL)
+ hwcap |= HWCAP_LRCPC;
+
+ if (ID_AA64ISAR1_FCMA(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_FCMA_IMPL)
+ hwcap |= HWCAP_FCMA;
+
+ if (ID_AA64ISAR1_JSCVT(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_JSCVT_IMPL)
+ hwcap |= HWCAP_JSCVT;
+
+ if (ID_AA64ISAR1_DPB(cpu_desc[cpu].id_aa64isar1) == ID_AA64ISAR1_DPB_IMPL)
+ hwcap |= HWCAP_DCPOP;
+
+ if (ID_AA64PFR0_SVE(cpu_desc[cpu].id_aa64pfr0) == ID_AA64PFR0_SVE_IMPL)
+ hwcap |= HWCAP_SVE;
+
+ switch (ID_AA64PFR0_ADV_SIMD(cpu_desc[cpu].id_aa64pfr0)) {
+ case ID_AA64PFR0_ADV_SIMD_IMPL:
+ hwcap |= HWCAP_ASIMD;
+ break;
+ case ID_AA64PFR0_ADV_SIMD_HP:
+ hwcap |= HWCAP_ASIMD | HWCAP_ASIMDDP;
+ break;
+ default:
+ break;
+ }
+
+ switch (ID_AA64PFR0_FP(cpu_desc[cpu].id_aa64pfr0)) {
+ case ID_AA64PFR0_FP_IMPL:
+ hwcap |= HWCAP_FP;
+ break;
+ case ID_AA64PFR0_FP_HP:
+ hwcap |= HWCAP_FP | HWCAP_FPHP;
+ break;
+ default:
+ break;
+ }
+
+ return (hwcap);
+}
+
+static void
print_cpu_features(u_int cpu)
{
struct sbuf *sb;
int printed;
+ printf("%s: cpu=%d cpu_print_regs=%x\n", __func__, cpu, cpu_print_regs);
sb = sbuf_new_auto();
sbuf_printf(sb, "CPU%3d: %s %s r%dp%d", cpu,
cpu_desc[cpu].cpu_impl_name, cpu_desc[cpu].cpu_part_name,
@@ -484,8 +585,10 @@
"hardware bugs that may cause the incorrect operation of "
"atomic operations.\n");
- if (cpu != 0 && cpu_print_regs == 0)
+ if (cpu != 0 && cpu_print_regs == 0) {
+ printf("cpu_print_reg = %d cpu = %d\n", cpu_print_regs, cpu);
return;
+ }
#define SEP_STR ((printed++) == 0) ? "" : ","
Index: sys/arm64/include/cpu.h
===================================================================
--- sys/arm64/include/cpu.h
+++ sys/arm64/include/cpu.h
@@ -160,7 +160,6 @@
void fork_trampoline(void);
void identify_cpu(void);
void install_cpu_errata(void);
-void print_cpu_features(u_int);
void swi_vm(void *v);
#define CPU_AFFINITY(cpu) __cpu_affinity[(cpu)]
Index: sys/arm64/include/elf.h
===================================================================
--- sys/arm64/include/elf.h
+++ sys/arm64/include/elf.h
@@ -87,4 +87,34 @@
#define ET_DYN_LOAD_ADDR 0x100000
#endif
+/* HWCAP */
+
+#define HWCAP_FP 0x00000001
+#define HWCAP_ASIMD 0x00000002
+#define HWCAP_EVTSTRM 0x00000004
+#define HWCAP_AES 0x00000008
+#define HWCAP_PMULL 0x00000010
+#define HWCAP_SHA1 0x00000020
+#define HWCAP_SHA2 0x00000040
+#define HWCAP_CRC32 0x00000080
+#define HWCAP_ATOMICS 0x00000100
+#define HWCAP_FPHP 0x00000200
+#define HWCAP_CPUID 0x00000400
+#define HWCAP_ASIMDRDM 0x00000800
+#define HWCAP_JSCVT 0x00001000
+#define HWCAP_FCMA 0x00002000
+#define HWCAP_LRCPC 0x00004000
+#define HWCAP_DCPOP 0x00008000
+#define HWCAP_SHA3 0x00010000
+#define HWCAP_SM3 0x00020000
+#define HWCAP_SM4 0x00040000
+#define HWCAP_ASIMDDP 0x00080000
+#define HWCAP_SHA512 0x00100000
+#define HWCAP_SVE 0x00200000
+#define HWCAP_ASIMDFHM 0x00400000
+#define HWCAP_DIT 0x00800000
+#define HWCAP_USCAT 0x01000000
+#define HWCAP_ILRCPC 0x02000000
+#define HWCAP_FLAGM 0x04000000
+
#endif /* !_MACHINE_ELF_H_ */

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 12, 8:28 AM (45 m, 51 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26892304
Default Alt Text
D17137.id56656.diff (5 KB)

Event Timeline